// algorithm standard header
#pragma once
#ifndef _ALGORITHM_
#define _ALGORITHM_
#ifndef RC_INVOKED
#include <memory>

#ifdef  _MSC_VER
 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma warning(disable: 4244)
#endif  /* _MSC_VER */

_STD_BEGIN

		// COMMON SORT PARAMETERS
const int _ISORT_MAX = 32;	// maximum size for insertion sort

		// TEMPLATE FUNCTION for_each
template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Func);
	_CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First));
	_CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last));
	for (; _ChkFirst != _ChkLast; ++_ChkFirst)
		_Func(*_ChkFirst);
	return (_Func);
	}

		// TEMPLATE FUNCTION find
template<class _InIt, class _Ty>
inline
	_InIt _Find(_InIt _First, _InIt _Last, const _Ty& _Val)
	{	// find first matching _Val
	_DEBUG_RANGE(_First, _Last);
	for (; _First != _Last; ++_First)
		if (*_First == _Val)
			break;
	return (_First);
	}

inline const char *_Find(const char *_First, const char *_Last, int _Val)
	{	// find first char that matches _Val
	_DEBUG_RANGE(_First, _Last);
	_First = (const char *)::memchr(_First, _Val, _Last - _First);
	return (_First == 0 ? _Last : _First);
	}

inline const signed char *_Find(const signed char *_First,
	const signed char *_Last, int _Val)
	{	// find first signed char that matches _Val
	_DEBUG_RANGE(_First, _Last);
	_First = (const signed char *)::memchr(_First, _Val,
		_Last - _First);
	return (_First == 0 ? _Last : _First);
	}

inline const unsigned char *_Find(const unsigned char *_First,
	const unsigned char *_Last, int _Val)
	{	// find first unsigned char that matches _Val
	_DEBUG_RANGE(_First, _Last);
	_First = (const unsigned char *)::memchr(_First, _Val,
		_Last - _First);
	return (_First == 0 ? _Last : _First);
	}

template<class _InIt, class _Ty>
inline
	_InIt find(_InIt _First, _InIt _Last, const _Ty& _Val)
	{	// find first matching _Val
	_ASSIGN_FROM_BASE(_First,
		_Find(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val));
	return (_First);
	}

		// TEMPLATE FUNCTION find_if
template<class _InIt,
	class _Pr> inline
	_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// find first satisfying _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (; _First != _Last; ++_First)
		if (_Pred(*_First))
			break;
	return (_First);
	}

template<class _InIt,
	class _Pr> inline
	_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// find first satisfying _Pred
	_ASSIGN_FROM_BASE(_First,
		_Find_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_First);
	}

		// TEMPLATE FUNCTION adjacent_find
template<class _FwdIt> inline
	_FwdIt _Adjacent_find(_FwdIt _First, _FwdIt _Last)
	{	// find first matching successor
	_DEBUG_RANGE(_First, _Last);
	for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; )
		if (*_Firstb == *_First)
			return (_Firstb);
	return (_Last);
	}

template<class _FwdIt> inline
	_FwdIt adjacent_find(_FwdIt _First, _FwdIt _Last)
	{	// find first matching successor
	_ASSIGN_FROM_BASE(_First,
		_Adjacent_find(_CHECKED_BASE(_First), _CHECKED_BASE(_Last)));
	return (_First);
	}

		// TEMPLATE FUNCTION adjacent_find WITH PRED
template<class _FwdIt,
	class _Pr> inline
	_FwdIt _Adjacent_find(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find first satisfying _Pred with successor
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; )
		if (_Pred(*_Firstb, *_First))
			return (_Firstb);
	return (_Last);
	}

template<class _FwdIt,
	class _Pr> inline
	_FwdIt adjacent_find(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find first satisfying _Pred with successor
	_ASSIGN_FROM_BASE(_First,
		_Adjacent_find(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_First);
	}

		// TEMPLATE FUNCTION count
template<class _InIt,
	class _Ty> inline
	typename iterator_traits<_InIt>::difference_type
		_Count(_InIt _First, _InIt _Last, const _Ty& _Val)
	{	// count elements that match _Val
	_DEBUG_RANGE(_First, _Last);
	typename iterator_traits<_InIt>::difference_type _Cnt = 0;

	for (; _First != _Last; ++_First)
		if (*_First == _Val)
			++_Cnt;
	return (_Cnt);
	}

template<class _InIt,
	class _Ty> inline
	typename iterator_traits<_InIt>::difference_type
		count(_InIt _First, _InIt _Last, const _Ty& _Val)
	{	// count elements that match _Val
	return _Count(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val);
	}

		// TEMPLATE FUNCTION count_if
template<class _InIt,
	class _Pr> inline
	typename iterator_traits<_InIt>::difference_type
		_Count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// count elements satisfying _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	typename iterator_traits<_InIt>::difference_type _Count = 0;

	for (; _First != _Last; ++_First)
		if (_Pred(*_First))
			++_Count;
	return (_Count);
	}

template<class _InIt,
	class _Pr> inline
	typename iterator_traits<_InIt>::difference_type
		count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// count elements satisfying _Pred
	return _Count_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred);
	}

		// TEMPLATE FUNCTION search
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2> inline
	_FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *)
	{	// find first [_First2, _Last2) match
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);

	for (; _Count2 <= _Count1; ++_First1, --_Count1)
		{	// room for match, try it
		_FwdIt1 _Mid1 = _First1;
		for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2)
			if (_Mid2 == _Last2)
				return (_First1);
			else if (!(*_Mid1 == *_Mid2))
				break;
		}
	return (_Last1);
	}

template<class _FwdIt1,
	class _FwdIt2> inline
	_FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2)
	{	// find first [_First2, _Last2) match
	_ASSIGN_FROM_BASE(_First1,
		_Search(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
			_Dist_type(_First1), _Dist_type(_First2)));
	return _First1;
	}

		// TEMPLATE FUNCTION search WITH PRED
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2,
	class _Pr> inline
	_FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *)
	{	// find first [_First2, _Last2) satisfying _Pred
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_DEBUG_POINTER(_Pred);
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);

	for (; _Count2 <= _Count1; ++_First1, --_Count1)
		{	// room for match, try it
		_FwdIt1 _Mid1 = _First1;
		for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2)
			if (_Mid2 == _Last2)
				return (_First1);
			else if (!_Pred(*_Mid1, *_Mid2))
				break;
		}
	return (_Last1);
	}

template<class _FwdIt1,
	class _FwdIt2,
	class _Pr> inline
	_FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
	{	// find first [_First2, _Last2) satisfying _Pred
	_ASSIGN_FROM_BASE(_First1,
		_Search(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred,
			_Dist_type(_First1), _Dist_type(_First2)));
	return _First1;
	}

		// TEMPLATE FUNCTION search_n
template<class _FwdIt1,
	class _Diff2,
	class _Ty> inline
	_FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val, forward_iterator_tag)
	{	// find first _Count * _Val match, forward iterators
	_DEBUG_RANGE(_First1, _Last1);

	if (_Count <= 0)
		return (_First1);

	for (; _First1 != _Last1; ++_First1)
		if (*_First1 == _Val)
			{	// found start of possible match, check it out
			_FwdIt1 _Mid1  = _First1;

			for (_Diff2 _Count1 = _Count; ; )
				if (--_Count1 == 0)
					return (_First1);	// found rest of match, report it
				else if (++_Mid1 == _Last1)
					return (_Last1);	// short match at end
				else if (!(*_Mid1 == _Val))
					break;	// short match not at end

			_First1 = _Mid1;	// pick up just beyond failed match
			}
	return (_Last1);
	}

template<class _FwdIt1,
	class _Diff2,
	class _Ty> inline
	_FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val, random_access_iterator_tag)
	{	// find first _Count * _Val match, random-access iterators
	_DEBUG_RANGE(_First1, _Last1);

	if (_Count <= 0)
		return (_First1);

	_FwdIt1 _Oldfirst1 = _First1;
	for (_Diff2 _Inc = 0; _Count <= _Last1 - _Oldfirst1; )
		{	// enough room, look for a match
		_First1 = _Oldfirst1 + _Inc;
		if (*_First1 == _Val)
			{	// found part of possible match, check it out
			_Diff2 _Count1 = _Count;
			_FwdIt1 _Mid1 = _First1;

			for (; _Oldfirst1 != _First1 && _First1[-1] == _Val; --_First1)
				--_Count1;	// back up over any skipped prefix

			if (_Count1 <= _Last1 - _Mid1)
				for (; ; )	// enough left, test suffix
					if (--_Count1 == 0)
						return (_First1);	// found rest of match, report it
					else if (!(*++_Mid1 == _Val))
						break;	// short match not at end

			_Oldfirst1 = ++_Mid1;	// failed match, take small jump
			_Inc = 0;
			}
		else
			{	// no match, take big jump and back up as needed
			_Oldfirst1 = _First1 + 1;
			_Inc = _Count - 1;
			}
		}
	return (_Last1);
	}

template<class _FwdIt1,
	class _Diff2,
	class _Ty> inline
	_FwdIt1 search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val)
	{	// find first _Count * _Val match
	_ASSIGN_FROM_BASE(_First1,
		_Search_n(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _Count, _Val,
			_Iter_cat(_First1)));
	return _First1;
	}

		// TEMPLATE FUNCTION search_n WITH PRED
template<class _FwdIt1,
	class _Diff2,
	class _Ty,
	class _Pr> inline
	_FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val, _Pr _Pred, forward_iterator_tag)
	{	// find first _Count * _Val satisfying _Pred, forward iterators
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_POINTER(_Pred);

	if (_Count <= 0)
		return (_First1);

	for (; _First1 != _Last1; ++_First1)
		if (_Pred(*_First1, _Val))
			{	// found start of possible match, check it out
			_FwdIt1 _Mid1  = _First1;

			for (_Diff2 _Count1 = _Count; ; )
				if (--_Count1 == 0)
					return (_First1);	// found rest of match, report it
				else if (++_Mid1 == _Last1)
					return (_Last1);	// short match at end
				else if (!_Pred(*_Mid1, _Val))
					break;	// short match not at end

			_First1 = _Mid1;	// pick up just beyond failed match
			}
	return (_Last1);
	}

template<class _FwdIt1,
	class _Diff2,
	class _Ty,
	class _Pr> inline
	_FwdIt1 _Search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val, _Pr _Pred, random_access_iterator_tag)
	{	// find first _Count * _Val satisfying _Pred, random-access iterators
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_POINTER(_Pred);

	if (_Count <= 0)
		return (_First1);

	_FwdIt1 _Oldfirst1 = _First1;
	for (; _Count <= _Last1 - _Oldfirst1; )
		{	// enough room, look for a match 
		if (_Pred(*_First1, _Val))
			{	// found part of possible match, check it out
			_Diff2 _Count1 = _Count;
			_FwdIt1 _Mid1  = _First1;

			for (; _Oldfirst1 != _First1 && _Pred(_First1[-1], _Val);
				--_First1)
				--_Count1;	// back up over any skipped prefix

			if (_Count1 <= _Last1 - _Mid1)
				for (; ; )	// enough left, test suffix
					if (--_Count1 == 0)
						return (_First1);	// found rest of match, report it
					else if (!_Pred(*++_Mid1, _Val))
						break;	// short match not at end

			_Oldfirst1 = ++_Mid1;	// failed match, take small jump
			_First1 = _Oldfirst1;
			}
		else
			{	// no match, take big jump and back up as needed
			_Oldfirst1 = _First1 + 1;
			_First1 += _Count;
			}
		}
	return (_Last1);
	}

template<class _FwdIt1,
	class _Diff2,
	class _Ty,
	class _Pr> inline
	_FwdIt1 search_n(_FwdIt1 _First1, _FwdIt1 _Last1,
		_Diff2 _Count, const _Ty& _Val, _Pr _Pred)
	{	// find first _Count * _Val satisfying _Pred
	_ASSIGN_FROM_BASE(_First1,
		_Search_n(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _Count, _Val, _Pred,
			_Iter_cat(_First1)));
	return _First1;
	}

		// TEMPLATE FUNCTION find_end
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2> inline
	_FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *)
	{	// find last [_First2, _Last2) match
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);
	_FwdIt1 _Ans = _Last1;

	if (0 < _Count2)
		for (; _Count2 <= _Count1; ++_First1, --_Count1)
			{	// room for match, try it
			_FwdIt1 _Mid1 = _First1;
			for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
				if (!(*_Mid1 == *_Mid2))
					break;
				else if (++_Mid2 == _Last2)
					{	// potential answer, save it
					_Ans = _First1;
					break;
					}
			}
	return (_Ans);
	}

template<class _FwdIt1,
	class _FwdIt2> inline
	_FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2)
	{	// find last [_First2, _Last2) match
	_ASSIGN_FROM_BASE(_First1,
		_Find_end(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
			_Dist_type(_First1), _Dist_type(_First2)));
	return _First1;
	}

		// TEMPLATE FUNCTION find_end WITH PRED
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2,
	class _Pr> inline
	_FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *)
	{	// find last [_First2, _Last2) satisfying _Pred
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_DEBUG_POINTER(_Pred);
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);
	_FwdIt1 _Ans = _Last1;

	if (0 < _Count2)
		for (; _Count2 <= _Count1; ++_First1, --_Count1)
			{	// room for match, try it
			_FwdIt1 _Mid1 = _First1;
			for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
				if (!_Pred(*_Mid1, *_Mid2))
					break;
				else if (++_Mid2 == _Last2)
					{	// potential answer, save it
					_Ans = _First1;
					break;
					}
			}
	return (_Ans);
	}

template<class _FwdIt1,
	class _FwdIt2,
	class _Pr> inline
	_FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
	{	// find last [_First2, _Last2) satisfying _Pred
	_ASSIGN_FROM_BASE(_First1,
		_Find_end(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred,
			_Dist_type(_First1), _Dist_type(_First2)));
	return _First1;
	}

		// TEMPLATE FUNCTION find_first_of
template<class _FwdIt1,
	class _FwdIt2> inline
	_FwdIt1 _Find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2)
	{	// look for one of [_First2, _Last2) that matches element
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	for (; _First1 != _Last1; ++_First1)
		for (_FwdIt2 _Mid2 = _First2; _Mid2 != _Last2; ++_Mid2)
			if (*_First1 == *_Mid2)
				return (_First1);
	return (_First1);
	}

template<class _FwdIt1,
	class _FwdIt2> inline
	_FwdIt1 find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2)
	{	// look for one of [_First2, _Last2) that matches element
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_ASSIGN_FROM_BASE(_First1,
		_Find_first_of(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2)));
	return _First1;
	}

		// TEMPLATE FUNCTION find_first_of WITH PRED
template<class _FwdIt1,
	class _FwdIt2,
	class _Pr> inline
	_FwdIt1 _Find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
	{	// look for one of [_First2, _Last2) satisfying _Pred with element
	_DEBUG_POINTER(_Pred);
	for (; _First1 != _Last1; ++_First1)
		for (_FwdIt2 _Mid2 = _First2; _Mid2 != _Last2; ++_Mid2)
			if (_Pred(*_First1, *_Mid2))
				return (_First1);
	return (_First1);
	}

template<class _FwdIt1,
	class _FwdIt2,
	class _Pr> inline
	_FwdIt1 find_first_of(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
	{	// look for one of [_First2, _Last2) satisfying _Pred with element
	_ASSIGN_FROM_BASE(_First1,
		_Find_first_of(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred));
	return (_First1);
	}

		// TEMPLATE FUNCTION iter_swap
template<class _FwdIt1,
	class _FwdIt2> inline
	void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
	{	// swap *_Left and *_Right
	swap(*_Left, *_Right);
	}

		// TEMPLATE FUNCTION swap_ranges
template<class _FwdIt1, class _FwdIt2, class _FwdItCats>
inline
	_FwdIt2 _Swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2,
		_FwdItCats, _Range_checked_iterator_tag)
	{	// swap [_First1, _Last1) with [_First2, ...)
	_DEBUG_RANGE(_First1, _Last1);
	for (; _First1 != _Last1; ++_First1, ++_First2)
		std::iter_swap(_First1, _First2);
	return (_First2);
	}

#if _SECURE_SCL
template<class _FwdIt1, class _FwdIt2>
inline
	_FwdIt2 _Swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// swap [_First1, _Last1) with [_First2, ...)
	// if _FwdIt2 is range checked, this will make sure there is enough space
	_FwdIt2 _Result = _First2 + (_Last1 - _First1);
	_Swap_ranges(_First1, _Last1, _CHECKED_BASE(_First2),
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return (_Result);
	}
#endif

#if _SECURE_SCL

template<class _FwdIt1, class _FwdIt2>
inline
_IF_CHK(_FwdIt2) swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt1, class _FwdElem2, size_t _Size>
inline
_FwdElem2* swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdElem2 (&_First2)[_Size])
	{
		return (swap_ranges(_First1, _Last1, _STDEXT make_checked_array_iterator(_First2, _Size)).base());
	}

template<class _FwdIt1, class _FwdIt2>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_FwdIt2) swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

#else

template<class _FwdIt1, class _FwdIt2>
inline
	_FwdIt2 swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION transform WITH UNARY OP
template<class _InIt, class _OutIt, class _Fn1, class _InOutItCat>
inline
	_OutIt _Transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func,
		_InOutItCat, _Range_checked_iterator_tag)
	{	// transform [_First, _Last) with _Func
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Func);
	for (; _First != _Last; ++_First, ++_Dest)
		*_Dest = _Func(*_First);
	return (_Dest);
	}

#if _SECURE_SCL
template<class _InIt, class _OutIt, class _Fn1>
inline
	_OutIt _Transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// transform [_First, _Last) with _Func
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last - _First);
	_Transform(_First, _Last, _CHECKED_BASE(_Dest), _Func,
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return (_Result);
	}
#endif

#if _SECURE_SCL

template<class _InIt, class _OutIt, class _Fn1>
inline
_IF_CHK(_OutIt) transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
	return _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Fn1, size_t _Size>
inline
_OutElem* transform(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Fn1 _Func)
	{
	return (transform(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Func).base());
	}

template<class _InIt, class _OutIt, class _Fn1>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
	return _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt, class _OutIt, class _Fn1>
inline
	_OutIt transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
	return _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION transform WITH BINARY OP
template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InItCats, class _InOutItCat>
inline
	_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func,
		_InItCats, _InOutItCat,
		_Range_checked_iterator_tag, _Range_checked_iterator_tag)
	{	// transform [_First1, _Last1) and [_First2, _Last2) with _Func
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Func);
	for (; _First1 != _Last1; ++_First1, ++_First2, ++_Dest)
		*_Dest = _Func(*_First1, *_First2);
	return (_Dest);
	}

#if _SECURE_SCL
template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
	_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func,
		random_access_iterator_tag, random_access_iterator_tag,
		_Range_checked_iterator_tag, _Range_checked_iterator_tag)
	{	// transform [_First1, _Last1) and [_First2, _Last2) with _Func
	// for range checked iterators, this will make sure there is enough space
	_InIt2 _Last2 = _First2 + (_Last1 - _First1); (_Last2);
	_OutIt _Result = _Dest + (_Last1 - _First1);
	_Transform(_First1, _Last1, _CHECKED_BASE(_First2),
		_CHECKED_BASE(_Dest), _Func,
		forward_iterator_tag(), forward_iterator_tag(),
		_Range_checked_iterator_tag(), _Range_checked_iterator_tag());
	return _Result;
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InOutItCat>
inline
	_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func,
		random_access_iterator_tag, _InOutItCat,
		_Range_checked_iterator_tag, _Range_checked_iterator_tag)
	{	// transform [_First1, _Last1) and [_First2, _Last2) with _Func
	// for range checked iterators, this will make sure there is enough space
	_InIt2 _Last2 = _First2 + (_Last1 - _First1); (_Last2);
	return _Transform(_First1, _Last1, _CHECKED_BASE(_First2),
		_Dest, _Func,
		forward_iterator_tag(), forward_iterator_tag(),
		_Range_checked_iterator_tag(), _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InItCats>
inline
	_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func,
		_InItCats, random_access_iterator_tag,
		_Range_checked_iterator_tag, _Range_checked_iterator_tag)
	{	// transform [_First1, _Last1) and [_First2, _Last2) with _Func
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last1 - _First1);
	_Transform(_First1, _Last1, _First2,
		_CHECKED_BASE(_Dest), _Func,
		forward_iterator_tag(), forward_iterator_tag(),
		_Range_checked_iterator_tag(), _Range_checked_iterator_tag());
	return _Result;
	}
#endif

#if _SECURE_SCL

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
_IF_CHK2_(_InIt2, _OutIt, _OutIt) transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
	return _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
		_Iter_random(_First1, _First2), _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InElem2, class _OutElem, class _Fn2, size_t _SizeFirst2, size_t _SizeDest>
inline
_OutElem* transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (transform(_First1, _Last1,
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest),
		_Func).base());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Fn2, size_t _SizeDest>
inline
_IF_CHK_(_InIt2, _OutElem*) transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (_Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest), _Func,
		_Iter_random(_First1, _First2), _Iter_cat(_First1),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()).base());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Fn2, size_t _SizeDest>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK_(_InIt2, _OutElem*) transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (_Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest), _Func,
		_Iter_random(_First1, _First2), _Iter_cat(_First1),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()).base());
	}

template<class _InIt1, class _InElem2, class _OutIt, class _Fn2, size_t _SizeFirst2>
inline
_IF_CHK(_OutIt) transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutIt _Dest, _Fn2 _Func)
	{
	return (_Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_Dest, _Func,
		_Iter_cat(_First1), _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt1, class _InElem2, class _OutIt, class _Fn2, size_t _SizeFirst2>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutIt _Dest, _Fn2 _Func)
	{
	return (_Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_Dest, _Func,
		_Iter_cat(_First1), _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK2_(_InIt2, _OutIt, _OutIt) transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
	return _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
		_Iter_random(_First1, _First2), _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
	_OutIt transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
	return _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
		_Iter_random(_First1, _First2), _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION replace
template<class _FwdIt,
	class _Ty> inline
	void _Replace(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// replace each matching _Oldval with _Newval
	_DEBUG_RANGE(_First, _Last);
	for (; _First != _Last; ++_First)
		if (*_First == _Oldval)
			*_First = _Newval;
	}

template<class _FwdIt,
	class _Ty> inline
	void replace(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// replace each matching _Oldval with _Newval
	_Replace(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Oldval, _Newval);
	}

		// TEMPLATE FUNCTION replace_if
template<class _FwdIt,
	class _Pr,
	class _Ty> inline
	void _Replace_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred, const _Ty& _Val)
	{	// replace each satisfying _Pred with _Val
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (; _First != _Last; ++_First)
		if (_Pred(*_First))
			*_First = _Val;
	}

template<class _FwdIt,
	class _Pr,
	class _Ty> inline
	void replace_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred, const _Ty& _Val)
	{	// replace each satisfying _Pred with _Val
	_Replace_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred, _Val);
	}

		// TEMPLATE FUNCTION replace_copy
template<class _InIt, class _OutIt, class _Ty, class _InOutItCat>
inline
	_OutIt _Replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval,
		_InOutItCat, _Range_checked_iterator_tag)
	{	// copy replacing each matching _Oldval with _Newval
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	for (; _First != _Last; ++_First, ++_Dest)
		*_Dest = *_First == _Oldval ? _Newval : *_First;
	return (_Dest);
	}

#if _SECURE_SCL
template<class _InIt, class _OutIt, class _Ty>
inline
	_OutIt _Replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy replacing each matching _Oldval with _Newval
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last - _First);
	_Replace_copy(_First, _Last, _CHECKED_BASE(_Dest),
		_Oldval, _Newval,
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return (_Result);
	}
#endif

#if _SECURE_SCL

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_IF_CHK(_OutIt) replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Ty, size_t _Size>
inline
_OutElem* replace_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size],
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return (replace_copy(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Oldval, _Newval).base());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION replace_copy_if
template<class _InIt, class _OutIt, class _Pr, class _Ty, class _InOutItCat>
inline
	_OutIt _Replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val, _InOutItCat, _Range_checked_iterator_tag)
	{	// copy replacing each satisfying _Pred with _Val
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Pred);
	for (; _First != _Last; ++_First, ++_Dest)
		*_Dest = _Pred(*_First) ? _Val : *_First;
	return (_Dest);
	}

#if _SECURE_SCL
template<class _InIt, class _OutIt, class _Pr, class _Ty>
inline
	_OutIt _Replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy replacing each satisfying _Pred with _Val
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last - _First);
	_Replace_copy_if(_First, _Last, _CHECKED_BASE(_Dest),
		_Pred, _Val,
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return (_Result);
	}
#endif

#if _SECURE_SCL

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
_IF_CHK(_OutIt) replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Pr, class _Ty, size_t _Size>
inline
_OutElem* replace_copy_if(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size],
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return (replace_copy_if(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Pred, _Val).base());
	}

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
	_OutIt replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION generate
template<class _FwdIt,
	class _Fn0> inline
	void _Generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func)
	{	// replace [_First, _Last) with _Func()
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Func);
	for (; _First != _Last; ++_First)
		*_First = _Func();
	}

template<class _FwdIt,
	class _Fn0> inline
	void generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func)
	{	// replace [_First, _Last) with _Func()
	_Generate(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Func);
	}

		// TEMPLATE FUNCTION generate_n
template<class _OutIt, class _Diff, class _Fn0, class _OutItCat>
inline
	void _Generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func,
		_OutItCat, _Range_checked_iterator_tag)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Func);
	for (; 0 < _Count; --_Count, ++_Dest)
		*_Dest = _Func();
	}

#if _SECURE_SCL
template<class _OutIt, class _Diff, class _Fn0>
inline
	void _Generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + _Count;
	_Generate_n(_CHECKED_BASE(_Dest), _Count, _Func,
		forward_iterator_tag(), _Range_checked_iterator_tag());
	}
#endif

#if _SECURE_SCL

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
_IF_CHK_(_OutIt, void) generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_Generate_n(_Dest, _Count, _Func,
		_Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

template<class _OutElem, class _Diff, class _Fn0, size_t _Size>
inline
void generate_n(_OutElem (&_Dest)[_Size], _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	generate_n(_STDEXT make_checked_array_iterator(_Dest, _Size), _Count, _Func);
	}

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK_(_OutIt, void) generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_Generate_n(_Dest, _Count, _Func,
		_Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
	void generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_Generate_n(_Dest, _Count, _Func,
		_Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION remove_copy
template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt _Remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val, _Range_checked_iterator_tag)
	{	// copy omitting each matching _Val
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	for (; _First != _Last; ++_First)
		if (!(*_First == _Val))
			*_Dest++ = *_First;
	return (_Dest);
	}

#if _SECURE_SCL

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_IF_CHK(_OutIt) remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
	return _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val, _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Ty, size_t _Size>
inline
_OutElem* remove_copy(_InIt _First, _InIt _Last,
		_OutElem (&_Dest)[_Size], const _Ty& _Val)
	{	// copy omitting each matching _Val
	return (remove_copy(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Val).base());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
	return _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
	return _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION remove_copy_if
template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt _Remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	// copy omitting each element satisfying _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Pred);
	for (; _First != _Last; ++_First)
		if (!_Pred(*_First))
			*_Dest++ = *_First;
	return (_Dest);
	}

#if _SECURE_SCL

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* remove_copy_if(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return (remove_copy_if(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION remove
template<class _FwdIt,
	class _Ty> inline
	_FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	{	// remove each matching _Val
	_First = find(_First, _Last, _Val);
	if (_First == _Last)
		return (_First);	// empty sequence, all done
	else
		{	// nonempty sequence, worth doing
		_FwdIt _First1 = _First;
		return (_STDEXT unchecked_remove_copy(++_First1, _Last, _First, _Val));
		}
	}

		// TEMPLATE FUNCTION remove_if
template<class _FwdIt,
	class _Pr> inline
	_FwdIt remove_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// remove each satisfying _Pred
	_First = std::find_if(_First, _Last, _Pred);
	if (_First == _Last)
		return (_First);	// empty sequence, all done
	else
		{	// nonempty sequence, worth doing
		_FwdIt _First1 = _First;
		return (_STDEXT unchecked_remove_copy_if(++_First1, _Last, _First, _Pred));
		}
	}

		// TEMPLATE FUNCTION unique
template<class _FwdIt> inline
	_FwdIt _Unique(_FwdIt _First, _FwdIt _Last)
	{	// remove each matching previous
	_DEBUG_RANGE(_First, _Last);
	for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; )
		if (*_Firstb == *_First)
			{	// copy down
			for (; ++_First != _Last; )
				if (!(*_Firstb == *_First))
					*++_Firstb = *_First;
			return (++_Firstb);
			}
	return (_Last);
	}

template<class _FwdIt> inline
	_FwdIt unique(_FwdIt _First, _FwdIt _Last)
	{	// remove each matching previous
	_ASSIGN_FROM_BASE(_Last,
		_Unique(_CHECKED_BASE(_First), _CHECKED_BASE(_Last)));
	return (_Last);
	}

		// TEMPLATE FUNCTION unique WITH PRED
template<class _FwdIt,
	class _Pr> inline
	_FwdIt _Unique(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// remove each satisfying _Pred with previous
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (_FwdIt _Firstb; (_Firstb = _First) != _Last && ++_First != _Last; )
		if (_Pred(*_Firstb, *_First))
			{	// copy down
			for (; ++_First != _Last; )
				if (!_Pred(*_Firstb, *_First))
					*++_Firstb = *_First;
			return (++_Firstb);
			}
	return (_Last);
	}

template<class _FwdIt,
	class _Pr> inline
	_FwdIt unique(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// remove each satisfying _Pred with previous
	_ASSIGN_FROM_BASE(_Last,
		_Unique(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_Last);
	}

		// TEMPLATE FUNCTION unique_copy
template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Ty *, _Range_checked_iterator_tag)
	{	// copy compressing pairs that match, input iterators
	_DEBUG_POINTER(_Dest);
	_Ty _Val = *_First;

	for (*_Dest++ = _Val; ++_First != _Last; )
		if (!(_Val == *_First))
			_Val = *_First, *_Dest++ = _Val;
	return (_Dest);
	}

template<class _InIt,
	class _OutIt> inline
	_OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		input_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs that match, input iterators
	return (_Unique_copy(_First, _Last, _Dest, _Val_type(_First), _Range_checked_iterator_tag()));
	}

template<class _FwdIt,
	class _OutIt> inline
	_OutIt _Unique_copy(_FwdIt _First, _FwdIt _Last, _OutIt _Dest,
		forward_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs that match, forward iterators
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	_FwdIt _Firstb = _First;
	for (*_Dest++ = *_Firstb; ++_First != _Last; )
		if (!(*_Firstb == *_First))
			_Firstb = _First, *_Dest++ = *_Firstb;
	return (_Dest);
	}

template<class _BidIt,
	class _OutIt> inline
	_OutIt _Unique_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		bidirectional_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs that match, bidirectional iterators
	return (_Unique_copy(_First, _Last, _Dest, forward_iterator_tag(), _Range_checked_iterator_tag()));
	}

template<class _RanIt,
	class _OutIt> inline
	_OutIt _Unique_copy(_RanIt _First, _RanIt _Last, _OutIt _Dest,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs that match, random-access iterators
	return (_Unique_copy(_First, _Last, _Dest, forward_iterator_tag(), _Range_checked_iterator_tag()));
	}

#if _SECURE_SCL

template<class _InIt,
	class _OutIt> inline
_IF_CHK(_OutIt) unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt, class _OutElem, size_t _Size>
inline
_OutElem* unique_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size])
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		(unique_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base()));
	}

template<class _InIt,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

#else

template<class _InIt,
	class _OutIt> inline
	_OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

#endif

		// TEMPLATE FUNCTION unique_copy WITH PRED
template<class _InIt,
	class _OutIt,
	class _Ty,
	class _Pr> inline
	_OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred,
		_Ty *, _Range_checked_iterator_tag)
	{	// copy compressing pairs satisfying _Pred, input iterators
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Pred);
	_Ty _Val = *_First;

	for (*_Dest++ = _Val; ++_First != _Last; )
		if (!_Pred(_Val, *_First))
			_Val = *_First, *_Dest++ = _Val;
	return (_Dest);
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt _Unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred,
		input_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs satisfying _Pred, input iterators
	return (_Unique_copy(_First, _Last, _Dest, _Pred, _Val_type(_First), _Range_checked_iterator_tag()));
	}

template<class _FwdIt,
	class _OutIt,
	class _Pr> inline
	_OutIt _Unique_copy(_FwdIt _First, _FwdIt _Last, _OutIt _Dest, _Pr _Pred,
		forward_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs satisfying _Pred, forward iterators
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	_DEBUG_POINTER(_Pred);
	_FwdIt _Firstb = _First;

	for (*_Dest++ = *_Firstb; ++_First != _Last; )
		if (!_Pred(*_Firstb, *_First))
			_Firstb = _First, *_Dest++ = *_Firstb;
	return (_Dest);
	}

template<class _BidIt,
	class _OutIt,
	class _Pr> inline
	_OutIt _Unique_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest, _Pr _Pred,
		bidirectional_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs satisfying _Pred, bidirectional iterators
	return (_Unique_copy(_First, _Last, _Dest, _Pred,
		forward_iterator_tag(), _Range_checked_iterator_tag()));
	}

template<class _RanIt,
	class _OutIt,
	class _Pr> inline
	_OutIt _Unique_copy(_RanIt _First, _RanIt _Last, _OutIt _Dest, _Pr _Pred,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy compressing pairs satisfying _Pred, random-access iterators
	return (_Unique_copy(_First, _Last, _Dest, _Pred,
		forward_iterator_tag(), _Range_checked_iterator_tag()));
	}

#if _SECURE_SCL

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* unique_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: (unique_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base()));
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

#else

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

#endif

		// TEMPLATE FUNCTION reverse
template<class _BidIt> inline
	void _Reverse(_BidIt _First, _BidIt _Last, bidirectional_iterator_tag)
	{	// reverse elements in [_First, _Last), bidirectional iterators
	for (; _First != _Last && _First != --_Last; ++_First)
		std::iter_swap(_First, _Last);
	}

template<class _RanIt> inline
	void _Reverse(_RanIt _First, _RanIt _Last, random_access_iterator_tag)
	{	// reverse elements in [_First, _Last), random-access iterators
	_DEBUG_RANGE(_First, _Last);
	for (; _First < _Last; ++_First)
		std::iter_swap(_First, --_Last);
	}

template<class _BidIt> inline
	void reverse(_BidIt _First, _BidIt _Last)
	{	// reverse elements in [_First, _Last)
	_Reverse(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Iter_cat(_First));
	}

		// TEMPLATE FUNCTION reverse_copy
template<class _BidIt, class _OutIt, class _InOutItCat>
inline
	_OutIt _Reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_InOutItCat, _Range_checked_iterator_tag)
	{	// copy reversing elements in [_First, _Last)
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Dest);
	for (; _First != _Last; ++_Dest)
		*_Dest = *--_Last;
	return (_Dest);
	}

#if _SECURE_SCL
template<class _BidIt, class _OutIt>
inline
	_OutIt _Reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy reversing elements in [_First, _Last)
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last - _First);
	_Reverse_copy(_First, _Last, _CHECKED_BASE(_Dest),
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return (_Result);
	}
#endif

#if _SECURE_SCL

template<class _BidIt,
	class _OutIt> inline
_IF_CHK(_OutIt) reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
	return _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, size_t _Size>
inline
_OutElem* reverse_copy(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size])
	{	// copy reversing elements in [_First, _Last)
	return (reverse_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _BidIt,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
	return _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _BidIt,
	class _OutIt> inline
	_OutIt reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
	return _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION rotate
template<class _FwdIt> inline
	void _Rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last,
		forward_iterator_tag)
	{	// rotate [_First, _Last), forward iterators
	for (_FwdIt _Next = _Mid; ; )
		{	// swap [_First, ...) into place
		std::iter_swap(_First, _Next);
		if (++_First == _Mid)
			if (++_Next == _Last)
				break;	// done, quit
			else
				_Mid = _Next;	// mark end of next interval
		else if (++_Next == _Last)
			_Next = _Mid;	// wrap to last end
		}
	}

template<class _BidIt> inline
	void _Rotate(_BidIt _First, _BidIt _Mid, _BidIt _Last,
		bidirectional_iterator_tag)
	{	// rotate [_First, _Last), bidirectional iterators
	std::reverse(_First, _Mid);
	std::reverse(_Mid, _Last);
	std::reverse(_First, _Last);
	}

template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Rotate(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Diff *, _Ty *)
	{	// rotate [_First, _Last), random-access iterators
	_DEBUG_RANGE(_First, _Mid);
	_DEBUG_RANGE(_Mid, _Last);
	_Diff _Shift = _Mid - _First;
	_Diff _Count = _Last - _First;

	for (_Diff _Factor = _Shift; _Factor != 0; )
		{	// find subcycle count as GCD of shift count and length
		_Diff _Tmp = _Count % _Factor;
		_Count = _Factor, _Factor = _Tmp;
		}

	if (_Count < _Last - _First)
		for (; 0 < _Count; --_Count)
			{	// rotate each subcycle
			_RanIt _Hole = _First + _Count;
			_RanIt _Next = _Hole;
			_Ty _Holeval = *_Hole;
			_RanIt _Next1 = _Next + _Shift == _Last ? _First : _Next + _Shift;
			while (_Next1 != _Hole)
				{	// percolate elements back around subcycle
				*_Next = *_Next1;
				_Next = _Next1;
				_Next1 = _Shift < _Last - _Next1 ? _Next1 + _Shift
					: _First + (_Shift - (_Last - _Next1));
				}
			*_Next = _Holeval;
			}
	}

template<class _RanIt> inline
	void _Rotate(_RanIt _First, _RanIt _Mid, _RanIt _Last,
			random_access_iterator_tag)
	{	// rotate [_First, _Last), random-access iterators
	_Rotate(_First, _Mid, _Last, _Dist_type(_First), _Val_type(_First));
	}

template<class _FwdIt> inline
	void rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last)
	{	// rotate [_First, _Last)
	if (_First != _Mid && _Mid != _Last)
		_Rotate(_CHECKED_BASE(_First), _CHECKED_BASE(_Mid), _CHECKED_BASE(_Last), _Iter_cat(_First));
	}

		// TEMPLATE FUNCTION rotate_copy
template<class _FwdIt,
	class _OutIt> inline
	_OutIt _Rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest, _Range_checked_iterator_tag)
	{	// copy rotating [_First, _Last)
	_Dest = _STDEXT unchecked_copy(_Mid, _Last, _Dest);
	return (_STDEXT unchecked_copy(_First, _Mid, _Dest));
	}

#if _SECURE_SCL

template<class _FwdIt, class _OutIt>
inline
_IF_CHK(_OutIt) rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{
		return _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt, class _OutElem, size_t _Size>
inline
_OutElem* rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutElem (&_Dest)[_Size])
	{
		return (rotate_copy(_First, _Mid, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _FwdIt, class _OutIt>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{
		return _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _FwdIt, class _OutIt>
inline
	_OutIt rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{
		return _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION random_shuffle
template<class _RanIt,
	class _Diff> inline
	void _Random_shuffle(_RanIt _First, _RanIt _Last, _Diff *)
	{	// shuffle [_First, _Last)
	_DEBUG_RANGE(_First, _Last);
	const int _RANDOM_BITS = 15;	// minimum random bits from rand()
	const int _RANDOM_MAX = (1U << _RANDOM_BITS) - 1;

	_RanIt _Next = _First;
	for (unsigned long _Index = 2; ++_Next != _Last; ++_Index)
		{	// assume unsigned long big enough for _Diff count
		unsigned long _Rm = _RANDOM_MAX;
		unsigned long _Rn = ::rand() & _RANDOM_MAX;
		for (; _Rm < _Index && _Rm != ~0UL;
			_Rm = _Rm << _RANDOM_BITS | _RANDOM_MAX)
			_Rn = _Rn << _RANDOM_BITS
				| (::rand() & _RANDOM_MAX);	// build random value

		std::iter_swap(_Next, _First + _Diff(_Rn % _Index));	// swap a pair
		}
	}

template<class _RanIt> inline
	void random_shuffle(_RanIt _First, _RanIt _Last)
	{	// shuffle [_First, _Last)
	if (_First != _Last)
		_Random_shuffle(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dist_type(_First));
	}

		// TEMPLATE FUNCTION random_shuffle WITH RANDOM FN
template<class _RanIt,
	class _Fn1,
	class _Diff> inline
	void _Random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func, _Diff *)
	{	// shuffle nonempty [_First, _Last) using random function _Func
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Func);
	_RanIt _Next = _First;

	for (_Diff _Index = 2; ++_Next != _Last; ++_Index)
		std::iter_swap(_Next, _First + _Diff(_Func(_Index) % _Index));
	}

template<class _RanIt,
	class _Fn1> inline
	void random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func)
	{	// shuffle [_First, _Last) using random function _Func
	if (_First != _Last)
		_Random_shuffle(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Func, _Dist_type(_First));
	}

		// TEMPLATE FUNCTION partition
template<class _BidIt,
	class _Pr> inline
	_BidIt _Partition(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// move elements satisfying _Pred to beginning of sequence
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (; ; ++_First)
		{	// find any out-of-order pair
		for (; _First != _Last && _Pred(*_First); ++_First)
			;	// skip in-place elements at beginning
		if (_First == _Last)
			break;	// done

		for (; _First != --_Last && !_Pred(*_Last); )
			;	// skip in-place elements at end
		if (_First == _Last)
			break;	// done

		std::iter_swap(_First, _Last);	// swap out-of-place pair and loop
		}
	return (_First);
	}

template<class _BidIt,
	class _Pr> inline
	_BidIt partition(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// move elements satisfying _Pred to beginning of sequence
	_ASSIGN_FROM_BASE(_First,
		_Partition(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_First);
	}

		// TEMPLATE FUNCTION stable_partition
template<class _BidIt,
	class _Pr,
	class _Diff,
	class _Ty> inline
	_BidIt _Stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred,
		_Diff _Count, _Temp_iterator<_Ty>& _Tempbuf)
	{	// partition preserving order of equivalents, using _Pred
	if (_Count == 0)
		return (_First);
	else if (_Count == 1)
		return (_Pred(*_First) ? _Last : _First);
	else if (_Count <= _Tempbuf._Maxlen())
		{	// temp buffer big enough, copy right partition out and back
		_BidIt _Next = _First;
		for (_Tempbuf._Init(); _First != _Last; ++_First)
			if (_Pred(*_First))
				*_Next++ = *_First;
			else
				*_Tempbuf++ = *_First;

		_STDEXT unchecked_copy(_Tempbuf._First(), _Tempbuf._Last(), _Next);	// copy back
		return (_Next);
		}
	else
		{	// temp buffer not big enough, divide and conquer
		_BidIt _Mid = _First;
		std::advance(_Mid, _Count / 2);

		_BidIt _Left = _Stable_partition(_First, _Mid, _Pred,
			_Count / 2, _Tempbuf);	// form L1R1 in left half
		_BidIt _Right = _Stable_partition(_Mid, _Last, _Pred,
			_Count - _Count / 2, _Tempbuf);	// form L2R2 in right half

		_Diff _Count1 = 0;
		_Distance(_Left, _Mid, _Count1);
		_Diff _Count2 = 0;
		_Distance(_Mid, _Right, _Count2);

		return (_Buffered_rotate(_Left, _Mid, _Right,
			_Count1, _Count2, _Tempbuf));	// rotate L1R1L2R2 to L1L2R1R2
		}
	}

template<class _BidIt,
	class _Pr,
	class _Diff,
	class _Ty> inline
	_BidIt _Stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred,
		_Diff *, _Ty *)
	{	// partition preserving order of equivalents, using _Pred
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	_Temp_iterator<_Ty> _Tempbuf(_Count);
	return (_Stable_partition(_First, _Last, _Pred, _Count, _Tempbuf));
	}

template<class _BidIt,
	class _Pr> inline
	_BidIt stable_partition(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// partition preserving order of equivalents, using _Pred
	if (_First != _Last)
		{
		_ASSIGN_FROM_BASE(_First,
			_Stable_partition(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred,
				_Dist_type(_First), _Val_type(_First)));
		}
	return _First;
	}

#ifndef _DEBUG_HEAP_IMPL
 #define _DEBUG_HEAP_IMPL _Debug_heap
#endif

 #if _HAS_ITERATOR_DEBUGGING
		// TEMPLATE FUNCTION _Debug_heap
template<class _RanIt> inline
	void _Debug_heap(_RanIt _First, _RanIt _Last)
	{	// test if range is a heap ordered by operator<
	if (_First != _Last)
		for (_RanIt _Root = _First; ++_First != _Last; ++_Root)
			if (_DEBUG_LT(*_Root, *_First))
				_DEBUG_ERROR("invalid heap");
			else if (++_First == _Last)
				break;
			else if (_DEBUG_LT(*_Root, *_First))
				_DEBUG_ERROR("invalid heap");
	}

		// TEMPLATE FUNCTION _Debug_heap WITH PRED
template<class _RanIt,
	class _Pr> inline
	void _Debug_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// test if range is a heap ordered by _Pred
	if (_First != _Last)
		for (_RanIt _Root = _First; ++_First != _Last; ++_Root)
			if (_DEBUG_LT_PRED(_Pred, *_Root, *_First))
				_DEBUG_ERROR("invalid heap");
			else if (++_First == _Last)
				break;
			else if (_DEBUG_LT_PRED(_Pred, *_Root, *_First))
				_DEBUG_ERROR("invalid heap");
	}

 #define _DEBUG_HEAP(first, last)	\
	_DEBUG_HEAP_IMPL(first, last)
 #define _DEBUG_HEAP_PRED(first, last, pred)	\
	_DEBUG_HEAP_IMPL(first, last, pred)

 #else /* _HAS_ITERATOR_DEBUGGING */
 #define _DEBUG_HEAP(first, last)
 #define _DEBUG_HEAP_PRED(first, last, pred)
 #endif /* _HAS_ITERATOR_DEBUGGING */

		// TEMPLATE FUNCTION push_heap
template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Push_heap(_RanIt _First, _Diff _Hole,
		_Diff _Top, _Ty _Val)
	{	// percolate _Hole to _Top or where _Val belongs, using operator<
	for (_Diff _Idx = (_Hole - 1) / 2;
		_Top < _Hole && _DEBUG_LT(*(_First + _Idx), _Val);
		_Idx = (_Hole - 1) / 2)
		{	// move _Hole up to parent
		*(_First + _Hole) = *(_First + _Idx);
		_Hole = _Idx;
		}

	*(_First + _Hole) = _Val;	// drop _Val into final hole
	}

template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Push_heap_0(_RanIt _First, _RanIt _Last, _Diff *, _Ty *)
	{	// push *_Last onto heap at [_First, _Last), using operator<
	_Diff _Count = _Last - _First;
	if (0 < _Count)
		std::_Push_heap(_First, _Count, _Diff(0), _Ty(*_Last));
	}

template<class _RanIt> inline
	void push_heap(_RanIt _First, _RanIt _Last)
	{	// push *(_Last - 1) onto heap at [_First, _Last - 1), using operator<
	_DEBUG_RANGE(_First, _Last);
	if (_First != _Last)
		{	// check and push to nontrivial heap
		_DEBUG_HEAP(_First, _Last - 1);
		std::_Push_heap_0(_CHECKED_BASE(_First), _CHECKED_BASE(--_Last),
			_Dist_type(_First), _Val_type(_First));
		}
	}

		// TEMPLATE FUNCTION push_heap WITH PRED
template<class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Push_heap(_RanIt _First, _Diff _Hole,
		_Diff _Top, _Ty _Val, _Pr _Pred)
	{	// percolate _Hole to _Top or where _Val belongs, using operator<
	for (_Diff _Idx = (_Hole - 1) / 2;
		_Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val);
		_Idx = (_Hole - 1) / 2)
		{	// move _Hole up to parent
		*(_First + _Hole) = *(_First + _Idx);
		_Hole = _Idx;
		}

	*(_First + _Hole) = _Val;	// drop _Val into final hole
	}

template<class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Push_heap_0(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *)
	{	// push *_Last onto heap at [_First, _Last), using _Pred
	_Diff _Count = _Last - _First;
	if (0 < _Count)
		std::_Push_heap(_First, _Count, _Diff(0), _Ty(*_Last), _Pred);
	}

template<class _RanIt,
	class _Pr> inline
	void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// push *(_Last - 1) onto heap at [_First, _Last - 1), using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	if (_First != _Last)
		{	// check and push to nontrivial heap
		_DEBUG_HEAP_PRED(_First, _Last - 1, _Pred);
		std::_Push_heap_0(_CHECKED_BASE(_First), _CHECKED_BASE(--_Last), _Pred,
			_Dist_type(_First), _Val_type(_First));
		}
	}

		// TEMPLATE FUNCTION pop_heap
template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Adjust_heap(_RanIt _First, _Diff _Hole, _Diff _Bottom, _Ty _Val)
	{	// percolate _Hole to _Bottom, then push _Val, using operator<
	_Diff _Top = _Hole;
	_Diff _Idx = 2 * _Hole + 2;

	for (; _Idx < _Bottom; _Idx = 2 * _Idx + 2)
		{	// move _Hole down to larger child
		if (_DEBUG_LT(*(_First + _Idx), *(_First + (_Idx - 1))))
			--_Idx;
		*(_First + _Hole) = *(_First + _Idx), _Hole = _Idx;
		}

	if (_Idx == _Bottom)
		{	// only child at bottom, move _Hole down to it
		*(_First + _Hole) = *(_First + (_Bottom - 1));
		_Hole = _Bottom - 1;
		}
	std::_Push_heap(_First, _Hole, _Top, _Val);
	}

template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Pop_heap(_RanIt _First, _RanIt _Last, _RanIt _Dest,
		_Ty _Val, _Diff *)
	{	// pop *_First to *_Dest and reheap, using operator<
	*_Dest = *_First;
	std::_Adjust_heap(_First, _Diff(0), _Diff(_Last - _First), _Val);
	}

template<class _RanIt,
	class _Ty> inline
	void _Pop_heap_0(_RanIt _First, _RanIt _Last, _Ty *)
	{	// pop *_First to *(_Last - 1) and reheap, using operator<
	_Pop_heap(_First, _Last - 1, _Last - 1,
		_Ty(*(_Last - 1)), _Dist_type(_First));
	}

template<class _RanIt> inline
	void pop_heap(_RanIt _First, _RanIt _Last)
	{	// pop *_First to *(_Last - 1) and reheap, using operator<
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_HEAP(_First, _Last);
	if (1 < _Last - _First)
		_Pop_heap_0(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val_type(_First));
	}

		// TEMPLATE FUNCTION pop_heap WITH PRED
template<class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Adjust_heap(_RanIt _First, _Diff _Hole, _Diff _Bottom,
		_Ty _Val, _Pr _Pred)
	{	// percolate _Hole to _Bottom, then push _Val, using _Pred
	_Diff _Top = _Hole;
	_Diff _Idx = 2 * _Hole + 2;

	for (; _Idx < _Bottom; _Idx = 2 * _Idx + 2)
		{	// move _Hole down to larger child
		if (_DEBUG_LT_PRED(_Pred, *(_First + _Idx), *(_First + (_Idx - 1))))
			--_Idx;
		*(_First + _Hole) = *(_First + _Idx), _Hole = _Idx;
		}

	if (_Idx == _Bottom)
		{	// only child at bottom, move _Hole down to it
		*(_First + _Hole) = *(_First + (_Bottom - 1));
		_Hole = _Bottom - 1;
		}
	std::_Push_heap(_First, _Hole, _Top, _Val, _Pred);
	}

template<class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Pop_heap(_RanIt _First, _RanIt _Last, _RanIt _Dest,
		_Ty _Val, _Pr _Pred, _Diff *)
	{	// pop *_First to *_Dest and reheap, using _Pred
	*_Dest = *_First;
	std::_Adjust_heap(_First, _Diff(0), _Diff(_Last - _First),
		_Val, _Pred);
	}

template<class _RanIt,
	class _Ty,
	class _Pr> inline
	void _Pop_heap_0(_RanIt _First, _RanIt _Last, _Pr _Pred, _Ty *)
	{	// pop *_First to *(_Last - 1) and reheap, using _Pred
	_Pop_heap(_First, _Last - 1, _Last - 1,
		_Ty(*(_Last - 1)), _Pred, _Dist_type(_First));
	}

template<class _RanIt,
	class _Pr> inline
	void pop_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// pop *_First to *(_Last - 1) and reheap, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_DEBUG_HEAP_PRED(_First, _Last, _Pred);
	if (1 < _Last - _First)
		_Pop_heap_0(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred, _Val_type(_First));
	}

		// TEMPLATE FUNCTION make_heap
template<class _RanIt,
	class _Diff,
	class _Ty> inline
	void _Make_heap(_RanIt _First, _RanIt _Last, _Diff *, _Ty *)
	{	// make nontrivial [_First, _Last) into a heap, using operator<
	_Diff _Bottom = _Last - _First;

	for (_Diff _Hole = _Bottom / 2; 0 < _Hole; )
		{	// reheap top half, bottom to top
		--_Hole;
		std::_Adjust_heap(_First, _Hole, _Bottom,
			_Ty(*(_First + _Hole)));
		}
	}

template<class _RanIt> inline
	void make_heap(_RanIt _First, _RanIt _Last)
	{	// make [_First, _Last) into a heap, using operator<
	_DEBUG_RANGE(_First, _Last);
	if (1 < _Last - _First)
		_Make_heap(_CHECKED_BASE(_First), _CHECKED_BASE(_Last),
			_Dist_type(_First), _Val_type(_First));
	}

		// TEMPLATE FUNCTION make_heap WITH PRED
template<class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *)
	{	// make nontrivial [_First, _Last) into a heap, using _Pred
	_Diff _Bottom = _Last - _First;
	for (_Diff _Hole = _Bottom / 2; 0 < _Hole; )
		{	// reheap top half, bottom to top
		--_Hole;
		std::_Adjust_heap(_First, _Hole, _Bottom,
			_Ty(*(_First + _Hole)), _Pred);
		}
	}

template<class _RanIt,
	class _Pr> inline
	void make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// make [_First, _Last) into a heap, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	if (1 < _Last - _First)
		_Make_heap(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred,
			_Dist_type(_First), _Val_type(_First));
	}

		// TEMPLATE FUNCTION sort_heap
template<class _RanIt> inline
	void _Sort_heap(_RanIt _First, _RanIt _Last)
	{	// order heap by repeatedly popping, using operator<
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_HEAP(_First, _Last);
	for (; 1 < _Last - _First; --_Last)
		std::pop_heap(_First, _Last);
	}

template<class _RanIt> inline
	void sort_heap(_RanIt _First, _RanIt _Last)
	{	// order heap by repeatedly popping, using operator<
	_DEBUG_HEAP(_First, _Last);
	_Sort_heap(_CHECKED_BASE(_First), _CHECKED_BASE(_Last));
	}

		// TEMPLATE FUNCTION sort_heap WITH PRED
template<class _RanIt,
	class _Pr> inline
	void _Sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// order heap by repeatedly popping, using _Pred
	for (; 1 < _Last - _First; --_Last)
		std::pop_heap(_First, _Last, _Pred);
	}

template<class _RanIt,
	class _Pr> inline
	void sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// order heap by repeatedly popping, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_DEBUG_HEAP_PRED(_First, _Last, _Pred);
	_Sort_heap(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred);
	}

		// TEMPLATE FUNCTION lower_bound
template<class _FwdIt,
	class _Ty,
	class _Diff> inline
	_FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *)
	{	// find first element not before _Val, using operator<
	_DEBUG_ORDER_SINGLE(_First, _Last, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);

	for (; 0 < _Count; )
		{	// divide and conquer, find half that contains answer
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE(_Mid, _Last, false);

		if (_DEBUG_LT(*_Mid, _Val))
			_First = ++_Mid, _Count -= _Count2 + 1;
		else
			_Count = _Count2;
		}
	return (_First);
	}

template<class _FwdIt,
	class _Ty> inline
	_FwdIt lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	{	// find first element not before _Val, using operator<
	_ASSIGN_FROM_BASE(_First,
		_Lower_bound(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val, _Dist_type(_First)));
	return _First;
	}

		// TEMPLATE FUNCTION lower_bound WITH PRED
template<class _FwdIt,
	class _Ty,
	class _Diff,
	class _Pr> inline
	_FwdIt _Lower_bound(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred, _Diff *)
	{	// find first element not before _Val, using _Pred
	_DEBUG_POINTER(_Pred);
	_DEBUG_ORDER_SINGLE_PRED(_First, _Last, _Pred, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	for (; 0 < _Count; )
		{	// divide and conquer, find half that contains answer
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE_PRED(_Mid, _Last, _Pred, false);

		if (_DEBUG_LT_PRED(_Pred, *_Mid, _Val))
			_First = ++_Mid, _Count -= _Count2 + 1;
		else
			_Count = _Count2;
		}
	return (_First);
	}

template<class _FwdIt,
	class _Ty,
	class _Pr> inline
	_FwdIt lower_bound(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred)
	{	// find first element not before _Val, using _Pred
	_ASSIGN_FROM_BASE(_First,
		_Lower_bound(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val, _Pred, _Dist_type(_First)));
	return _First;
	}

		// TEMPLATE FUNCTION upper_bound
template<class _FwdIt,
	class _Ty,
	class _Diff> inline
	_FwdIt _Upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Diff *)
	{	// find first element that _Val is before, using operator<
	_DEBUG_ORDER_SINGLE(_First, _Last, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	for (; 0 < _Count; )
		{	// divide and conquer, find half that contains answer
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE(_Mid, _Last, false);

		if (!_DEBUG_LT(_Val, *_Mid))
			_First = ++_Mid, _Count -= _Count2 + 1;
		else
			_Count = _Count2;
		}
	return (_First);
	}

template<class _FwdIt,
	class _Ty> inline
	_FwdIt upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	{	// find first element that _Val is before, using operator<
	_ASSIGN_FROM_BASE(_First,
		_Upper_bound(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val, _Dist_type(_First)));
	return _First;
	}

		// TEMPLATE FUNCTION upper_bound WITH PRED
template<class _FwdIt,
	class _Ty,
	class _Diff,
	class _Pr> inline
	_FwdIt _Upper_bound(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred, _Diff *)
	{	// find first element that _Val is before, using _Pred
	_DEBUG_POINTER(_Pred);
	_DEBUG_ORDER_SINGLE_PRED(_First, _Last, _Pred, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	for (; 0 < _Count; )
		{	// divide and conquer, find half that contains answer
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE_PRED(_Mid, _Last, _Pred, false);

		if (!_DEBUG_LT_PRED(_Pred, _Val, *_Mid))
			_First = ++_Mid, _Count -= _Count2 + 1;
		else
			_Count = _Count2;
		}
	return (_First);
	}

template<class _FwdIt,
	class _Ty,
	class _Pr> inline
	_FwdIt upper_bound(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred)
	{	// find first element that _Val is before, using _Pred
	_ASSIGN_FROM_BASE(_First,
		_Upper_bound(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Val, _Pred, _Dist_type(_First)));
	return _First;
	}

		// TEMPLATE FUNCTION equal_range
template<class _FwdIt,
	class _Ty,
	class _Diff> inline
	pair<_FwdIt, _FwdIt> _Equal_range(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Diff *)
	{	// find range equivalent to _Val, using operator<
	_DEBUG_ORDER_SINGLE(_First, _Last, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);

	for (; 0 < _Count; )
		{	// divide and conquer, check midpoint
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE(_Mid, _Last, false);

		if (_DEBUG_LT(*_Mid, _Val))
			{	// range begins above _Mid, loop
			_First = ++_Mid;
			_Count -= _Count2 + 1;
			}
		else if (_Val < *_Mid)
			_Count = _Count2;	// range in first half, loop
		else
			{	// range straddles mid, find each end and return
			_FwdIt _First2 = lower_bound(_First, _Mid, _Val);
			std::advance(_First, _Count);
			_FwdIt _Last2 = upper_bound(++_Mid, _First, _Val);
			return (pair<_FwdIt, _FwdIt>(_First2, _Last2));
			}
		}

	return (pair<_FwdIt, _FwdIt>(_First, _First));	// empty range
	}

template<class _FwdIt,
	class _Ty> inline
	pair<_FwdIt, _FwdIt> equal_range(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val)
	{	// find range equivalent to _Val, using operator<
	return (_Equal_range(_First, _Last, _Val, _Dist_type(_First)));
	}

		// TEMPLATE FUNCTION equal_range WITH PRED
template<class _FwdIt,
	class _Ty,
	class _Diff,
	class _Pr> inline
	pair<_FwdIt, _FwdIt> _Equal_range(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred, _Diff *)
	{	// find range equivalent to _Val, using _Pred
	_DEBUG_POINTER(_Pred);
	_DEBUG_ORDER_SINGLE_PRED(_First, _Last, _Pred, true);
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);

	for (; 0 < _Count; )
		{	// divide and conquer, check midpoint
		_Diff _Count2 = _Count / 2;
		_FwdIt _Mid = _First;
		std::advance(_Mid, _Count2);
		_DEBUG_ORDER_SINGLE_PRED(_Mid, _Last, _Pred, false);

		if (_DEBUG_LT_PRED(_Pred, *_Mid, _Val))
			{	// range begins above _Mid, loop
			_First = ++_Mid;
			_Count -= _Count2 + 1;
			}
		else if (_Pred(_Val, *_Mid))
			_Count = _Count2;	// range in first half, loop
		else
			{	// range straddles _Mid, find each end and return
			_FwdIt _First2 = lower_bound(_First, _Mid, _Val, _Pred);
			std::advance(_First, _Count);
			_FwdIt _Last2 = upper_bound(++_Mid, _First, _Val, _Pred);
			return (pair<_FwdIt, _FwdIt>(_First2, _Last2));
			}
		}

	return (pair<_FwdIt, _FwdIt>(_First, _First));	// empty range
	}

template<class _FwdIt,
	class _Ty,
	class _Pr> inline
	pair<_FwdIt, _FwdIt> equal_range(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred)
	{	// find range equivalent to _Val, using _Pred
	return (_Equal_range(_First, _Last, _Val, _Pred, _Dist_type(_First)));
	}

		// TEMPLATE FUNCTION binary_search
template<class _FwdIt,
	class _Ty> inline
	bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	{	// test if _Val equivalent to some element, using operator<
	_First = std::lower_bound(_First, _Last, _Val);
	return (_First != _Last && !(_Val < *_First));
	}

		// TEMPLATE FUNCTION binary_search WITH PRED
template<class _FwdIt,
	class _Ty,
	class _Pr> inline
	bool binary_search(_FwdIt _First, _FwdIt _Last,
		const _Ty& _Val, _Pr _Pred)
	{	// test if _Val equivalent to some element, using _Pred
	_First = std::lower_bound(_First, _Last, _Val, _Pred);
	return (_First != _Last && !_Pred(_Val, *_First));
	}

		// TEMPLATE FUNCTION merge
template<class _InIt1, class _InIt2, class _OutIt, class _InOutItCat>
inline
	_OutIt _Merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest,
		_InOutItCat, _Range_checked_iterator_tag)
	{	// copy merging ranges, both using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; ++_Dest)
		if (_DEBUG_LT(*_First2, *_First1))
			*_Dest = *_First2, ++_First2;
		else
			*_Dest = *_First1, ++_First1;

	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);	// copy any tail
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL
template<class _InIt1, class _InIt2, class _OutIt>
inline
	_OutIt _Merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	// copy merging ranges, both using operator<
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last1 - _First1) + (_Last2 - _First2);
	_Merge(_First1, _Last1, _First2, _Last2, _CHECKED_BASE(_Dest),
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return _Result;
	}
#endif

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// copy merging ranges, both using operator<
	return (merge(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION merge WITH PRED
template<class _InIt1, class _InIt2, class _OutIt, class _Pr, class _InOutItCat>
inline
	_OutIt _Merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred,
		_InOutItCat, _Range_checked_iterator_tag)
	{	//  copy merging ranges, both using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; ++_Dest)
		if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1))
			*_Dest = *_First2, ++_First2;
		else
			*_Dest = *_First1, ++_First1;

	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);	// copy any tail
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL
template<class _InIt1, class _InIt2, class _OutIt, class _Pr>
inline
	_OutIt _Merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred,
		random_access_iterator_tag, _Range_checked_iterator_tag)
	{	//  copy merging ranges, both using _Pred
	// for range checked iterators, this will make sure there is enough space
	_OutIt _Result = _Dest + (_Last1 - _First1) + (_Last2 - _First2);
	_Merge(_First1, _Last1, _First2, _Last2, _CHECKED_BASE(_Dest), _Pred, 
		forward_iterator_tag(), _Range_checked_iterator_tag());
	return _Result;
	}
#endif

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return (merge(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred,
		_Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION inplace_merge
template<class _BidIt,
	class _Diff,
	class _Ty> inline
	_BidIt _Buffered_rotate(_BidIt _First, _BidIt _Mid, _BidIt _Last,
		_Diff _Count1, _Diff _Count2, _Temp_iterator<_Ty>& _Tempbuf)
	{	// rotate [_First, _Last) using temp buffer
	if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen())
		{	// buffer left partition, then copy parts
		_STDEXT unchecked_copy(_First, _Mid, _Tempbuf._Init());
		_STDEXT unchecked_copy(_Mid, _Last, _First);
		return (_STDEXT unchecked_copy_backward(_Tempbuf._First(), _Tempbuf._Last(),
			_Last));
		}
	else if (_Count2 <= _Tempbuf._Maxlen())
		{	// buffer right partition, then copy parts
		_STDEXT unchecked_copy(_Mid, _Last, _Tempbuf._Init());
		_STDEXT unchecked_copy_backward(_First, _Mid, _Last);
		return (_STDEXT unchecked_copy(_Tempbuf._First(), _Tempbuf._Last(), _First));
		}
	else
		{	// buffer too small, rotate in place
		std::rotate(_First, _Mid, _Last);
		std::advance(_First, _Count2);
		return (_First);
		}
	}

template<class _BidIt1,
	class _BidIt2,
	class _BidIt3> inline
	_BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Range_checked_iterator_tag)
	{	// merge backwards to _Dest, using operator<
	for (; ; )
		if (_First1 == _Last1)
			return (_STDEXT unchecked_copy_backward(_First2, _Last2, _Dest));
		else if (_First2 == _Last2)
			return (_STDEXT unchecked_copy_backward(_First1, _Last1, _Dest));
		else if (_DEBUG_LT(*--_Last2, *--_Last1))
			*--_Dest = *_Last1, ++_Last2;
		else
			*--_Dest = *_Last2, ++_Last1;
	}

#if _SECURE_SCL

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
_IF_CHK(_BidIt3) _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_BidIt3) _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
	_BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

#endif

template<class _BidIt,
	class _Diff,
	class _Ty> inline
	void _Buffered_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last,
		_Diff _Count1, _Diff _Count2,
			_Temp_iterator<_Ty>& _Tempbuf)
	{	// merge [_First, _Mid) with [_Mid, _Last), using operator<
	if (_Count1 + _Count2 == 2)
		{	// order two one-element partitions
		if (_DEBUG_LT(*_Mid, *_First))
			std::iter_swap(_First, _Mid);
		}
	else if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen())
		{	// buffer left partition, then merge
		_STDEXT unchecked_copy(_First, _Mid, _Tempbuf._Init());
		_STDEXT unchecked_merge(_Tempbuf._First(), _Tempbuf._Last(), _Mid, _Last, _First);
		}
	else if (_Count2 <= _Tempbuf._Maxlen())
		{	// buffer right partition, then merge
		_STDEXT unchecked_copy(_Mid, _Last, _Tempbuf._Init());
		_STDEXT _Unchecked_merge_backward(_First, _Mid,
			_Tempbuf._First(), _Tempbuf._Last(), _Last);
		}
	else
		{	// buffer too small, divide and conquer
		_BidIt _Firstn, _Lastn;
		_Diff _Count1n, _Count2n;

		if (_Count2 < _Count1)
			{	// left larger, cut it in half and partition right to match
			_Count1n = _Count1 / 2, _Count2n = 0;
			_Firstn = _First;
			std::advance(_Firstn, _Count1n);
			_Lastn = std::lower_bound(_Mid, _Last, *_Firstn);
			_Distance(_Mid, _Lastn, _Count2n);
			}
		else
			{	// right larger, cut it in half and partition left to match
			_Count1n = 0, _Count2n = _Count2 / 2;
			_Lastn = _Mid;
			std::advance(_Lastn, _Count2n);
			_Firstn = std::upper_bound(_First, _Mid, *_Lastn);
			_Distance(_First, _Firstn, _Count1n);
			}

		_BidIt _Midn = _Buffered_rotate(_Firstn, _Mid, _Lastn,
			_Count1 - _Count1n, _Count2n, _Tempbuf);	// rearrange middle
		_Buffered_merge(_First, _Firstn, _Midn,
			_Count1n, _Count2n, _Tempbuf);	// merge each new part
		_Buffered_merge(_Midn, _Lastn, _Last,
			_Count1 - _Count1n, _Count2 - _Count2n, _Tempbuf);
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty> inline
	void _Inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last,
		_Diff *, _Ty *)
	{	// merge [_First, _Mid) with [_Mid, _Last), using operator<
	_DEBUG_ORDER(_First, _Mid);
	_DEBUG_ORDER(_Mid, _Last);
	_Diff _Count1 = 0;
	_Distance(_First, _Mid, _Count1);
	_Diff _Count2 = 0;
	_Distance(_Mid, _Last, _Count2);
	_Temp_iterator<_Ty> _Tempbuf(_Count1 < _Count2 ? _Count1 : _Count2);
	_Buffered_merge(_First, _Mid, _Last,
		_Count1, _Count2, _Tempbuf);
	}

template<class _BidIt> inline
	void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last)
	{	// merge [_First, _Mid) with [_Mid, _Last), using operator<
	if (_First != _Mid && _Mid != _Last)
		_Inplace_merge(_CHECKED_BASE(_First), _CHECKED_BASE(_Mid), _CHECKED_BASE(_Last),
			_Dist_type(_First), _Val_type(_First));
	}

		// TEMPLATE FUNCTION inplace_merge WITH PRED
template<class _BidIt1,
	class _BidIt2,
	class _BidIt3,
	class _Pr> inline
	_BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	// merge backwards to _Dest, using _Pred
	for (; ; )
		if (_First1 == _Last1)
			return (_STDEXT unchecked_copy_backward(_First2, _Last2, _Dest));
		else if (_First2 == _Last2)
			return (_STDEXT unchecked_copy_backward(_First1, _Last1, _Dest));
		else if (_DEBUG_LT_PRED(_Pred, *--_Last2, *--_Last1))
			*--_Dest = *_Last1, ++_Last2;
		else
			*--_Dest = *_Last2, ++_Last1;
	}

#if _SECURE_SCL

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
_IF_CHK(_BidIt3) _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_BidIt3) _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
	_BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

template<class _BidIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Buffered_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last,
		_Diff _Count1, _Diff _Count2,
			_Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred)
	{	// merge [_First, _Mid) with [_Mid, _Last), using _Pred
	if (_Count1 + _Count2 == 2)
		{	// order two one-element partitions
		if (_DEBUG_LT_PRED(_Pred, *_Mid, *_First))
			std::iter_swap(_First, _Mid);
		}
	else if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen())
		{	// buffer left partition, then merge
		_STDEXT unchecked_copy(_First, _Mid, _Tempbuf._Init());
		_STDEXT unchecked_merge(_Tempbuf._First(), _Tempbuf._Last(),
			_Mid, _Last, _First, _Pred);
		}
	else if (_Count2 <= _Tempbuf._Maxlen())
		{	// buffer right partition, then merge
		_STDEXT unchecked_copy(_Mid, _Last, _Tempbuf._Init());
		_STDEXT _Unchecked_merge_backward(_First, _Mid, _Tempbuf._First(), _Tempbuf._Last(),
			_Last, _Pred);
		}
	else
		{	// buffer too small, divide and conquer
		_BidIt _Firstn, _Lastn;
		_Diff _Count1n, _Count2n;
		if (_Count2 < _Count1)
			{	// left larger, cut it in half and partition right to match
			_Count1n = _Count1 / 2, _Count2n = 0;
			_Firstn = _First;
			std::advance(_Firstn, _Count1n);
			_Lastn = lower_bound(_Mid, _Last, *_Firstn, _Pred);
			_Distance(_Mid, _Lastn, _Count2n);
			}
		else
			{	// right larger, cut it in half and partition left to match
			_Count1n = 0, _Count2n = _Count2 / 2;
			_Lastn = _Mid;
			std::advance(_Lastn, _Count2n);
			_Firstn = upper_bound(_First, _Mid, *_Lastn, _Pred);
			_Distance(_First, _Firstn, _Count1n);
			}
		_BidIt _Midn = _Buffered_rotate(_Firstn, _Mid, _Lastn,
			_Count1 - _Count1n, _Count2n, _Tempbuf);	// rearrange middle
		_Buffered_merge(_First, _Firstn, _Midn,
			_Count1n, _Count2n, _Tempbuf, _Pred);	// merge each new part
		_Buffered_merge(_Midn, _Lastn, _Last,
			_Count1 - _Count1n, _Count2 - _Count2n, _Tempbuf, _Pred);
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred,
		_Diff *, _Ty *)
	{	// merge [_First, _Mid) with [_Mid, _Last), using _Pred
	_DEBUG_ORDER_PRED(_First, _Mid, _Pred);
	_DEBUG_ORDER_PRED(_Mid, _Last, _Pred);
	_Diff _Count1 = 0;
	_Distance(_First, _Mid, _Count1);
	_Diff _Count2 = 0;
	_Distance(_Mid, _Last, _Count2);
	_Temp_iterator<_Ty> _Tempbuf(_Count1 < _Count2 ? _Count1 : _Count2);
	_Buffered_merge(_First, _Mid, _Last,
		_Count1, _Count2, _Tempbuf, _Pred);
	}

template<class _BidIt,
	class _Pr> inline
	void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred)
	{	// merge [_First, _Mid) with [_Mid, _Last), using _Pred
	if (_First != _Mid && _Mid != _Last)
		_Inplace_merge(_CHECKED_BASE(_First), _CHECKED_BASE(_Mid), _CHECKED_BASE(_Last), _Pred,
			_Dist_type(_First), _Val_type(_First));
	}

		// TEMPLATE FUNCTION sort
template<class _BidIt,
	class _Ty> inline
	void _Insertion_sort1(_BidIt _First, _BidIt _Last, _Ty *)
	{	// insertion sort [_First, _Last), using operator<
	if (_First != _Last)
		for (_BidIt _Next = _First; ++_Next != _Last; )
			{	// order next element
			_BidIt _Next1 = _Next;
			_Ty _Val = *_Next;

			if (_DEBUG_LT(_Val, *_First))
				{	// found new earliest element, move to front
				_STDEXT unchecked_copy_backward(_First, _Next, ++_Next1);
				*_First = _Val;
				}
			else
				{	// look for insertion point after first
				for (_BidIt _First1 = _Next1;
					_DEBUG_LT(_Val, *--_First1);
					_Next1 = _First1)
					*_Next1 = *_First1;	// move hole down
				*_Next1 = _Val;	// insert element in hole
				}
			}
	}

template<class _BidIt> inline
	void _Insertion_sort(_BidIt _First, _BidIt _Last)
	{	// insertion sort [_First, _Last), using operator<
	std::_Insertion_sort1(_First, _Last, _Val_type(_First));
	}

template<class _RanIt> inline
	void _Med3(_RanIt _First, _RanIt _Mid, _RanIt _Last)
	{	// sort median of three elements to middle
	if (_DEBUG_LT(*_Mid, *_First))
		std::iter_swap(_Mid, _First);
	if (_DEBUG_LT(*_Last, *_Mid))
		std::iter_swap(_Last, _Mid);
	if (_DEBUG_LT(*_Mid, *_First))
		std::iter_swap(_Mid, _First);
	}

template<class _RanIt> inline
	void _Median(_RanIt _First, _RanIt _Mid, _RanIt _Last)
	{	// sort median element to middle
	if (40 < _Last - _First)
		{	// median of nine
		size_t _Step = (_Last - _First + 1) / 8;
		std::_Med3(_First, _First + _Step, _First + 2 * _Step);
		std::_Med3(_Mid - _Step, _Mid, _Mid + _Step);
		std::_Med3(_Last - 2 * _Step, _Last - _Step, _Last);
		std::_Med3(_First + _Step, _Mid, _Last - _Step);
		}
	else
		std::_Med3(_First, _Mid, _Last);
	}

template<class _RanIt> inline
	pair<_RanIt, _RanIt> _Unguarded_partition(_RanIt _First, _RanIt _Last)
	{	// partition [_First, _Last), using operator<
	_RanIt _Mid = _First + (_Last - _First) / 2;	// sort median to _Mid
	std::_Median(_First, _Mid, _Last - 1);
	_RanIt _Pfirst = _Mid;
	_RanIt _Plast = _Pfirst + 1;

	while (_First < _Pfirst
		&& !_DEBUG_LT(*(_Pfirst - 1), *_Pfirst)
		&& !(*_Pfirst < *(_Pfirst - 1)))
		--_Pfirst;
	while (_Plast < _Last
		&& !_DEBUG_LT(*_Plast, *_Pfirst)
		&& !(*_Pfirst < *_Plast))
		++_Plast;

	_RanIt _Gfirst = _Plast;
	_RanIt _Glast = _Pfirst;

	for (; ; )
		{	// partition
		for (; _Gfirst < _Last; ++_Gfirst)
			if (_DEBUG_LT(*_Pfirst, *_Gfirst))
				;
			else if (*_Gfirst < *_Pfirst)
				break;
			else
				std::iter_swap(_Plast++, _Gfirst);
		for (; _First < _Glast; --_Glast)
			if (_DEBUG_LT(*(_Glast - 1), *_Pfirst))
				;
			else if (*_Pfirst < *(_Glast - 1))
				break;
			else
				std::iter_swap(--_Pfirst, _Glast - 1);
		if (_Glast == _First && _Gfirst == _Last)
			return (pair<_RanIt, _RanIt>(_Pfirst, _Plast));

		if (_Glast == _First)
			{	// no room at bottom, rotate pivot upward
			if (_Plast != _Gfirst)
				std::iter_swap(_Pfirst, _Plast);
			++_Plast;
			std::iter_swap(_Pfirst++, _Gfirst++);
			}
		else if (_Gfirst == _Last)
			{	// no room at top, rotate pivot downward
			if (--_Glast != --_Pfirst)
				std::iter_swap(_Glast, _Pfirst);
			std::iter_swap(_Pfirst, --_Plast);
			}
		else
			std::iter_swap(_Gfirst++, --_Glast);
		}
	}

template<class _RanIt,
	class _Diff> inline
	void _Sort(_RanIt _First, _RanIt _Last, _Diff _Ideal)
	{	// order [_First, _Last), using operator<
	_Diff _Count;
	for (; _ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal; )
		{	// divide and conquer by quicksort
		pair<_RanIt, _RanIt> _Mid =
			std::_Unguarded_partition(_First, _Last);
		_Ideal /= 2, _Ideal += _Ideal / 2;	// allow 1.5 log2(N) divisions

		if (_Mid.first - _First < _Last - _Mid.second)
			{	// loop on second half
			std::_Sort(_First, _Mid.first, _Ideal);
			_First = _Mid.second;
			}
		else
			{	// loop on first half
			std::_Sort(_Mid.second, _Last, _Ideal);
			_Last = _Mid.first;
			}
		}

	if (_ISORT_MAX < _Count)
		{	// heap sort if too many divisions
		std::make_heap(_First, _Last);
		std::sort_heap(_First, _Last);
		}
	else if (1 < _Count)
		std::_Insertion_sort(_First, _Last);	// small
	}

template<class _RanIt> inline
	void sort(_RanIt _First, _RanIt _Last)
	{	// order [_First, _Last), using operator<
	_DEBUG_RANGE(_First, _Last);
	std::_Sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Last - _First);
	}

		// TEMPLATE FUNCTION sort WITH PRED
template<class _BidIt,
	class _Pr,
	class _Ty> inline
	void _Insertion_sort1(_BidIt _First, _BidIt _Last, _Pr _Pred, _Ty *)
	{	// insertion sort [_First, _Last), using _Pred
	if (_First != _Last)
		for (_BidIt _Next = _First; ++_Next != _Last; )
			{	// order next element
			_BidIt _Next1 = _Next;
			_Ty _Val = *_Next;

			if (_DEBUG_LT_PRED(_Pred, _Val, *_First))
				{	// found new earliest element, move to front
				_STDEXT unchecked_copy_backward(_First, _Next, ++_Next1);
				*_First = _Val;
				}
			else
				{	// look for insertion point after first
				for (_BidIt _First1 = _Next1;
					_DEBUG_LT_PRED(_Pred, _Val, *--_First1);
					_Next1 = _First1)
					*_Next1 = *_First1;	// move hole down
				*_Next1 = _Val;	// insert element in hole
				}
			}
	}

template<class _BidIt,
	class _Pr> inline
	void _Insertion_sort(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// insertion sort [_First, _Last), using _Pred
	std::_Insertion_sort1(_First, _Last, _Pred, _Val_type(_First));
	}

template<class _RanIt,
	class _Pr> inline
	void _Med3(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred)
	{	// sort median of three elements to middle
	if (_DEBUG_LT_PRED(_Pred, *_Mid, *_First))
		std::iter_swap(_Mid, _First);
	if (_DEBUG_LT_PRED(_Pred, *_Last, *_Mid))
		std::iter_swap(_Last, _Mid);
	if (_DEBUG_LT_PRED(_Pred, *_Mid, *_First))
		std::iter_swap(_Mid, _First);
	}

template<class _RanIt,
	class _Pr> inline
	void _Median(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred)
	{	// sort median element to middle
	if (40 < _Last - _First)
		{	// median of nine
		size_t _Step = (_Last - _First + 1) / 8;
		std::_Med3(_First, _First + _Step, _First + 2 * _Step, _Pred);
		std::_Med3(_Mid - _Step, _Mid, _Mid + _Step, _Pred);
		std::_Med3(_Last - 2 * _Step, _Last - _Step, _Last, _Pred);
		std::_Med3(_First + _Step, _Mid, _Last - _Step, _Pred);
		}
	else
		std::_Med3(_First, _Mid, _Last, _Pred);
	}

template<class _RanIt,
	class _Pr> inline
	pair<_RanIt, _RanIt> _Unguarded_partition(_RanIt _First, _RanIt _Last,
		_Pr _Pred)
	{	// partition [_First, _Last), using _Pred
	_RanIt _Mid = _First + (_Last - _First) / 2;
	std::_Median(_First, _Mid, _Last - 1, _Pred);
	_RanIt _Pfirst = _Mid;
	_RanIt _Plast = _Pfirst + 1;

	while (_First < _Pfirst
		&& !_DEBUG_LT_PRED(_Pred, *(_Pfirst - 1), *_Pfirst)
		&& !_Pred(*_Pfirst, *(_Pfirst - 1)))
		--_Pfirst;
	while (_Plast < _Last
		&& !_DEBUG_LT_PRED(_Pred, *_Plast, *_Pfirst)
		&& !_Pred(*_Pfirst, *_Plast))
		++_Plast;

	_RanIt _Gfirst = _Plast;
	_RanIt _Glast = _Pfirst;

	for (; ; )
		{	// partition
		for (; _Gfirst < _Last; ++_Gfirst)
			if (_DEBUG_LT_PRED(_Pred, *_Pfirst, *_Gfirst))
				;
			else if (_Pred(*_Gfirst, *_Pfirst))
				break;
			else
				std::iter_swap(_Plast++, _Gfirst);
		for (; _First < _Glast; --_Glast)
			if (_DEBUG_LT_PRED(_Pred, *(_Glast - 1), *_Pfirst))
				;
			else if (_Pred(*_Pfirst, *(_Glast - 1)))
				break;
			else
				std::iter_swap(--_Pfirst, _Glast - 1);
		if (_Glast == _First && _Gfirst == _Last)
			return (pair<_RanIt, _RanIt>(_Pfirst, _Plast));

		if (_Glast == _First)
			{	// no room at bottom, rotate pivot upward
			if (_Plast != _Gfirst)
				std::iter_swap(_Pfirst, _Plast);
			++_Plast;
			std::iter_swap(_Pfirst++, _Gfirst++);
			}
		else if (_Gfirst == _Last)
			{	// no room at top, rotate pivot downward
			if (--_Glast != --_Pfirst)
				std::iter_swap(_Glast, _Pfirst);
			std::iter_swap(_Pfirst, --_Plast);
			}
		else
			std::iter_swap(_Gfirst++, --_Glast);
		}
	}

template<class _RanIt,
	class _Diff,
	class _Pr> inline
	void _Sort(_RanIt _First, _RanIt _Last, _Diff _Ideal, _Pr _Pred)
	{	// order [_First, _Last), using _Pred
	_Diff _Count;
	for (; _ISORT_MAX < (_Count = _Last - _First) && 0 < _Ideal; )
		{	// divide and conquer by quicksort
		pair<_RanIt, _RanIt> _Mid =
			std::_Unguarded_partition(_First, _Last, _Pred);
		_Ideal /= 2, _Ideal += _Ideal / 2;	// allow 1.5 log2(N) divisions

		if (_Mid.first - _First < _Last - _Mid.second)
			{	// loop on second half
			std::_Sort(_First, _Mid.first, _Ideal, _Pred);
			_First = _Mid.second;
			}
		else
			{	// loop on first half
			std::_Sort(_Mid.second, _Last, _Ideal, _Pred);
			_Last = _Mid.first;
			}
		}

	if (_ISORT_MAX < _Count)
		{	// heap sort if too many divisions
		std::make_heap(_First, _Last, _Pred);
		std::sort_heap(_First, _Last, _Pred);
		}
	else if (1 < _Count)
		std::_Insertion_sort(_First, _Last, _Pred);	// small
	}

template<class _RanIt,
	class _Pr> inline
	void sort(_RanIt _First, _RanIt _Last, _Pr _Pred)
	{	// order [_First, _Last), using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	std::_Sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Last - _First, _Pred);
	}

		// TEMPLATE FUNCTION stable_sort
template<class _BidIt,
	class _OutIt,
	class _Diff> inline
	void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Range_checked_iterator_tag)
	{	// copy merging chunks, using operator<
	for (_Diff _Chunk2 = _Chunk * 2; _Chunk2 <= _Count; _Count -= _Chunk2)
		{	// copy merging pairs of adjacent chunks
		_BidIt _Mid1 = _First;
		std::advance(_Mid1, _Chunk);
		_BidIt _Mid2 = _Mid1;
		std::advance(_Mid2, _Chunk);

		_Dest = _STDEXT unchecked_merge(_First, _Mid1, _Mid1, _Mid2, _Dest);
		_First = _Mid2;
		}

	if (_Count <= _Chunk)
		_STDEXT unchecked_copy(_First, _Last, _Dest);	// copy partial last chunk
	else
		{	// copy merging whole and partial last chunk
		_BidIt _Mid = _First;
		std::advance(_Mid, _Chunk);

		_STDEXT unchecked_merge(_First, _Mid, _Mid, _Last, _Dest);
		}
	}

#if _SECURE_SCL

template<class _BidIt, class _OutIt, class _Diff>
inline
_IF_CHK_(_OutIt, void) _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, class _Diff, size_t _Size>
inline
void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size],
		_Diff _Chunk, _Diff _Count)
	{
		_Chunked_merge(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK_(_OutIt, void) _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

#else

template<class _BidIt, class _OutIt, class _Diff>
inline
	void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

#endif

template<class _BidIt,
	class _Diff,
	class _Ty> inline
	void _Buffered_merge_sort(_BidIt _First, _BidIt _Last, _Diff _Count,
		_Temp_iterator<_Ty>& _Tempbuf)
	{	// sort using temp buffer for merges, using operator<
	_BidIt _Mid = _First;
	for (_Diff _Nleft = _Count; _ISORT_MAX <= _Nleft; _Nleft -= _ISORT_MAX)
		{	// sort chunks
		_BidIt _Midend = _Mid;
		std::advance(_Midend, (int)_ISORT_MAX);

		std::_Insertion_sort(_Mid, _Midend);
		_Mid = _Midend;
		}
	std::_Insertion_sort(_Mid, _Last);	// sort partial last chunk

	for (_Diff _Chunk = _ISORT_MAX; _Chunk < _Count; _Chunk *= 2)
		{	// merge adjacent pairs of chunks to and from temp buffer
		_STDEXT _Unchecked_chunked_merge(_First, _Last, _Tempbuf._Init(),
			_Chunk, _Count);
		_STDEXT _Unchecked_chunked_merge(_Tempbuf._First(), _Tempbuf._Last(), _First,
			_Chunk *= 2, _Count);
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty> inline
	void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff _Count,
		_Temp_iterator<_Ty>& _Tempbuf)
	{	//  sort preserving order of equivalents, using operator<
	if (_Count <= _ISORT_MAX)
		std::_Insertion_sort(_First, _Last);	// small
	else
		{	// sort halves and merge
		_Diff _Count2 = (_Count + 1) / 2;
		_BidIt _Mid = _First;
		std::advance(_Mid, _Count2);

		if (_Count2 <= _Tempbuf._Maxlen())
			{	// temp buffer big enough, sort each half using buffer
			_Buffered_merge_sort(_First, _Mid, _Count2, _Tempbuf);
			_Buffered_merge_sort(_Mid, _Last, _Count - _Count2, _Tempbuf);
			}
		else
			{	// temp buffer not big enough, divide and conquer
			_Stable_sort(_First, _Mid, _Count2, _Tempbuf);
			_Stable_sort(_Mid, _Last, _Count - _Count2, _Tempbuf);
			}

		_Buffered_merge(_First, _Mid, _Last,
			_Count2, _Count - _Count2, _Tempbuf);	// merge sorted halves
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty> inline
	void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff *, _Ty *)
	{	// sort preserving order of equivalents, using operator<
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	_Temp_iterator<_Ty> _Tempbuf((_Count + 1) / 2);
	_Stable_sort(_First, _Last, _Count, _Tempbuf);
	}

template<class _BidIt> inline
	void stable_sort(_BidIt _First, _BidIt _Last)
	{	// sort preserving order of equivalents, using operator<
	_DEBUG_RANGE(_First, _Last);
	if (_First != _Last)
		{
		_Stable_sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dist_type(_First), _Val_type(_First));
		}
	}

		// TEMPLATE FUNCTION stable_sort WITH PRED
template<class _BidIt,
	class _OutIt,
	class _Diff,
	class _Pr> inline
	void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred, _Range_checked_iterator_tag)
	{	// copy merging chunks, using _Pred
	for (_Diff _Chunk2 = _Chunk * 2; _Chunk2 <= _Count; _Count -= _Chunk2)
		{	// copy merging pairs of adjacent chunks
		_BidIt _Mid1 = _First;
		std::advance(_Mid1, _Chunk);
		_BidIt _Mid2 = _Mid1;
		std::advance(_Mid2, _Chunk);

		_Dest = _STDEXT unchecked_merge(_First, _Mid1, _Mid1, _Mid2, _Dest, _Pred);
		_First = _Mid2;
		}

	if (_Count <= _Chunk)
		_STDEXT unchecked_copy(_First, _Last, _Dest);	// copy partial last chunk
	else
		{	// copy merging whole and partial last chunk
		_BidIt _Mid1 = _First;
		std::advance(_Mid1, _Chunk);

		_STDEXT unchecked_merge(_First, _Mid1, _Mid1, _Last, _Dest, _Pred);
		}
	}

#if _SECURE_SCL

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
_IF_CHK_(_OutIt, void) _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, class _Diff, class _Pr, size_t _Size>
inline
void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size],
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_Chunked_merge(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK_(_OutIt, void) _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
	void _Chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

template<class _BidIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Buffered_merge_sort(_BidIt _First, _BidIt _Last, _Diff _Count,
		_Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred)
	{	// sort using temp buffer for merges, using _Pred
	_BidIt _Mid = _First;
	for (_Diff _Nleft = _Count; _ISORT_MAX <= _Nleft; _Nleft -= _ISORT_MAX)
		{	// sort chunks
		_BidIt _Midn = _Mid;
		std::advance(_Midn, (int)_ISORT_MAX);

		std::_Insertion_sort(_Mid, _Midn, _Pred);
		_Mid = _Midn;
		}
	std::_Insertion_sort(_Mid, _Last, _Pred);	// sort partial last chunk

	for (_Diff _Chunk = _ISORT_MAX; _Chunk < _Count; _Chunk *= 2)
		{	// merge adjacent pairs of chunks to and from temp buffer
		_STDEXT _Unchecked_chunked_merge(_First, _Last, _Tempbuf._Init(),
			_Chunk, _Count, _Pred);
		_STDEXT _Unchecked_chunked_merge(_Tempbuf._First(), _Tempbuf._Last(), _First,
			_Chunk *= 2, _Count, _Pred);
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff _Count,
		_Temp_iterator<_Ty>& _Tempbuf, _Pr _Pred)
	{	// sort preserving order of equivalents, using _Pred
	if (_Count <= _ISORT_MAX)
		std::_Insertion_sort(_First, _Last, _Pred);	// small
	else
		{	// sort halves and merge
		_Diff _Count2 = (_Count + 1) / 2;
		_BidIt _Mid = _First;
		std::advance(_Mid, _Count2);

		if (_Count2 <= _Tempbuf._Maxlen())
			{	// temp buffer big enough, sort each half using buffer
			_Buffered_merge_sort(_First, _Mid, _Count2, _Tempbuf, _Pred);
			_Buffered_merge_sort(_Mid, _Last, _Count - _Count2,
				_Tempbuf, _Pred);
			}
		else
			{	// temp buffer not big enough, divide and conquer
			_Stable_sort(_First, _Mid, _Count2, _Tempbuf, _Pred);
			_Stable_sort(_Mid, _Last, _Count - _Count2, _Tempbuf, _Pred);
			}

		_Buffered_merge(_First, _Mid, _Last,
			_Count2, _Count - _Count2, _Tempbuf, _Pred);	// merge halves
		}
	}

template<class _BidIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	void _Stable_sort(_BidIt _First, _BidIt _Last, _Diff *, _Ty *, _Pr _Pred)
	{	// sort preserving order of equivalents, using _Pred
	_Diff _Count = 0;
	_Distance(_First, _Last, _Count);
	_Temp_iterator<_Ty> _Tempbuf((_Count + 1) / 2);
	_Stable_sort(_First, _Last, _Count, _Tempbuf, _Pred);
	}

template<class _BidIt,
	class _Pr> inline
	void stable_sort(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// sort preserving order of equivalents, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	if (_First != _Last)
		{
		_Stable_sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Last),
			_Dist_type(_First), _Val_type(_First), _Pred);
		}
	}

		// TEMPLATE FUNCTION partial_sort
template<class _RanIt,
	class _Ty> inline
	void _Partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Ty *)
	{	// order [First, _Last) up to _Mid, using operator<
	_DEBUG_RANGE(_First, _Mid);
	_DEBUG_RANGE(_Mid, _Last);
	std::make_heap(_First, _Mid);

	for (_RanIt _Next = _Mid; _Next < _Last; ++_Next)
		if (_DEBUG_LT(*_Next, *_First))
			_Pop_heap(_First, _Mid, _Next, _Ty(*_Next),
				_Dist_type(_First));	// replace top with new largest
	std::sort_heap(_First, _Mid);
	}

template<class _RanIt> inline
	void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last)
	{	// order [First, _Last) up to _Mid, using operator<
	_Partial_sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Mid), _CHECKED_BASE(_Last), _Val_type(_First));
	}

		// TEMPLATE FUNCTION partial_sort WITH PRED
template<class _RanIt,
	class _Ty,
	class _Pr> inline
	void _Partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last,
		_Pr _Pred, _Ty *)
	{	// order [First, _Last) up to _Mid, using _Pred
	_DEBUG_RANGE(_First, _Mid);
	_DEBUG_RANGE(_Mid, _Last);
	_DEBUG_POINTER(_Pred);
	std::make_heap(_First, _Mid, _Pred);

	for (_RanIt _Next = _Mid; _Next < _Last; ++_Next)
		if (_DEBUG_LT_PRED(_Pred, *_Next, *_First))
			_Pop_heap(_First, _Mid, _Next, _Ty(*_Next), _Pred,
				_Dist_type(_First));	// replace top with new largest
	std::sort_heap(_First, _Mid, _Pred);
	}

template<class _RanIt,
	class _Pr> inline
	void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred)
	{	// order [First, _Last) up to _Mid, using _Pred
	_Partial_sort(_CHECKED_BASE(_First), _CHECKED_BASE(_Mid), _CHECKED_BASE(_Last), _Pred, _Val_type(_First));
	}

		// TEMPLATE FUNCTION partial_sort_copy
template<class _InIt,
	class _RanIt,
	class _Diff,
	class _Ty> inline
	_RanIt _Partial_sort_copy(_InIt _First1, _InIt _Last1,
		_RanIt _First2, _RanIt _Last2, _Diff *, _Ty *)
	{	// copy [First1, _Last1) into [_First2, _Last2), using operator<
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_RanIt _Mid2 = _First2;
	for (; _First1 != _Last1 && _Mid2 != _Last2; ++_First1, ++_Mid2)
		*_Mid2 = *_First1;	// copy min(_Last1 - _First1, _Last2 - _First2)
	std::make_heap(_First2, _Mid2);

	for (; _First1 != _Last1; ++_First1)
		if (_DEBUG_LT(*_First1, *_First2))
			std::_Adjust_heap(_First2, _Diff(0), _Diff(_Mid2 - _First2),
				_Ty(*_First1));	// replace top with new largest

	std::sort_heap(_First2, _Mid2);
	return (_Mid2);
	}

template<class _InIt,
	class _RanIt> inline
	_RanIt partial_sort_copy(_InIt _First1, _InIt _Last1,
		_RanIt _First2, _RanIt _Last2)
	{	// copy [First1, _Last1) into [_First2, _Last2), using operator<
	if (_First1 != _Last1 && _First2 != _Last2)
        	_ASSIGN_FROM_BASE(_First2, _Partial_sort_copy(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), 
                          _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
                          _Dist_type(_First2), _Val_type(_First1)));
	return (_First2);
	}

		// TEMPLATE FUNCTION partial_sort_copy WITH PRED
template<class _InIt,
	class _RanIt,
	class _Diff,
	class _Ty,
	class _Pr> inline
	_RanIt _Partial_sort_copy(_InIt _First1, _InIt _Last1,
		_RanIt _First2, _RanIt _Last2, _Pr _Pred, _Diff *, _Ty *)
	{	// copy [First1, _Last1) into [_First2, _Last2) using _Pred
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_DEBUG_POINTER(_Pred);
	_RanIt _Mid2 = _First2;
	for (; _First1 != _Last1 && _Mid2 != _Last2; ++_First1, ++_Mid2)
		*_Mid2 = *_First1;	// copy min(_Last1 - _First1, _Last2 - _First2)
	std::make_heap(_First2, _Mid2, _Pred);

	for (; _First1 != _Last1; ++_First1)
		if (_DEBUG_LT_PRED(_Pred, *_First1, *_First2))
			std::_Adjust_heap(_First2, _Diff(0), _Diff(_Mid2 - _First2),
				_Ty(*_First1), _Pred);	// replace top with new largest

	std::sort_heap(_First2, _Mid2, _Pred);
	return (_Mid2);
	}

template<class _InIt,
	class _RanIt,
	class _Pr> inline
	_RanIt partial_sort_copy(_InIt _First1, _InIt _Last1,
		_RanIt _First2, _RanIt _Last2, _Pr _Pred)
	{	// copy [First1, _Last1) into [_First2, _Last2) using _Pred
	if (_First1 != _Last1 && _First2 != _Last2)
		_ASSIGN_FROM_BASE (_First2, _Partial_sort_copy(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
			_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred,
			_Dist_type(_First2), _Val_type(_First1)));
	return (_First2);
	}

		// TEMPLATE FUNCTION nth_element
template<class _RanIt> inline
	void _Nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last)
	{	// order Nth element, using operator<
	_DEBUG_RANGE(_First, _Last);
	for (; _ISORT_MAX < _Last - _First; )
		{	// divide and conquer, ordering partition containing Nth
		pair<_RanIt, _RanIt> _Mid =
			std::_Unguarded_partition(_First, _Last);

		if (_Mid.second <= _Nth)
			_First = _Mid.second;
		else if (_Mid.first <= _Nth)
			return;	// Nth inside fat pivot, done
		else
			_Last = _Mid.first;
		}

	std::_Insertion_sort(_First, _Last);	// sort any remainder
	}

template<class _RanIt> inline
	void nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last)
	{	// order Nth element, using operator<
	_Nth_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Nth), _CHECKED_BASE(_Last));
	}

		// TEMPLATE FUNCTION nth_element WITH PRED
template<class _RanIt,
	class _Pr> inline
	void _Nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last, _Pr _Pred)
	{	// order Nth element, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (; _ISORT_MAX < _Last - _First; )
		{	// divide and conquer, ordering partition containing Nth
		pair<_RanIt, _RanIt> _Mid =
			std::_Unguarded_partition(_First, _Last, _Pred);

		if (_Mid.second <= _Nth)
			_First = _Mid.second;
		else if (_Mid.first <= _Nth)
			return;	// Nth inside fat pivot, done
		else
			_Last = _Mid.first;
		}

	std::_Insertion_sort(_First, _Last, _Pred);	// sort any remainder
	}

template<class _RanIt,
	class _Pr> inline
	void nth_element(_RanIt _First, _RanIt _Nth, _RanIt _Last, _Pr _Pred)
	{	// order Nth element, using _Pred
	_Nth_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Nth), _CHECKED_BASE(_Last), _Pred);
	}

		// TEMPLATE FUNCTION includes
template<class _InIt1,
	class _InIt2> inline
	bool _Includes(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2)
	{	// test if all [_First1, _Last1) in [_First2, _Last2), using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT(*_First2, *_First1))
			return (false);
		else if (*_First1 < *_First2)
			++_First1;
		else
			++_First1, ++_First2;
	return (_First2 == _Last2);
	}

template<class _InIt1,
	class _InIt2> inline
	bool includes(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2)
	{	// test if all [_First1, _Last1) in [_First2, _Last2), using operator<
	return _Includes(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2));
	}

		// TEMPLATE FUNCTION includes WITH PRED
template<class _InIt1,
	class _InIt2,
	class _Pr> inline
	bool _Includes(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _Pr _Pred)
	{	// test if set [_First1, _Last1) in [_First2, _Last2), using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1))
			return (false);
		else if (_Pred(*_First1, *_First2))
			++_First1;
		else
			++_First1, ++_First2;
	return (_First2 == _Last2);
	}

template<class _InIt1,
	class _InIt2,
	class _Pr> inline
	bool includes(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _Pr _Pred)
	{	// test if set [_First1, _Last1) in [_First2, _Last2), using _Pred
	return _Includes(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Pred);
	}

		// TEMPLATE FUNCTION set_union
template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt _Set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Range_checked_iterator_tag)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT(*_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (*_First2 < *_First1)
			*_Dest++ = *_First2, ++_First2;
		else
			*_Dest++ = *_First1, ++_First1, ++_First2;
	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (set_union(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_union WITH PRED
template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt _Set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT_PRED(_Pred, *_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (_Pred(*_First2, *_First1))
			*_Dest++ = *_First2, ++_First2;
		else
			*_Dest++ = *_First1, ++_First1, ++_First2;
	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (set_union(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_intersection
template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt _Set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Range_checked_iterator_tag)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT(*_First1, *_First2))
			++_First1;
		else if (*_First2 < *_First1)
			++_First2;
		else
			*_Dest++ = *_First1++, ++_First2;
	return (_Dest);
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (set_intersection(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_intersection WITH PRED
template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt _Set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT_PRED(_Pred, *_First1, *_First2))
			++_First1;
		else if (_Pred(*_First2, *_First1))
			++_First2;
		else
			*_Dest++ = *_First1++, ++_First2;
	return (_Dest);
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (set_intersection(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_difference
template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt _Set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Range_checked_iterator_tag)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT(*_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (*_First2 < *_First1)
			++_First2;
		else
			++_First1, ++_First2;
	return (_STDEXT unchecked_copy(_First1, _Last1, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return (set_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_difference WITH PRED
template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt _Set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT_PRED(_Pred, *_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (_Pred(*_First2, *_First1))
			++_First2;
		else
			++_First1, ++_First2;
	return (_STDEXT unchecked_copy(_First1, _Last1, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return (set_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_symmetric_difference
template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt _Set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Range_checked_iterator_tag)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	_DEBUG_ORDER(_First1, _Last1);
	_DEBUG_ORDER(_First2, _Last2);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT(*_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (*_First2 < *_First1)
			*_Dest++ = *_First2, ++_First2;
		else
			++_First1, ++_First2;
	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (set_symmetric_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION set_symmetric_difference WITH PRED
template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt _Set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred, _Range_checked_iterator_tag)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	_DEBUG_ORDER_PRED(_First1, _Last1, _Pred);
	_DEBUG_ORDER_PRED(_First2, _Last2, _Pred);
	_DEBUG_POINTER(_Dest);
	for (; _First1 != _Last1 && _First2 != _Last2; )
		if (_DEBUG_LT_PRED(_Pred, *_First1, *_First2))
			*_Dest++ = *_First1, ++_First1;
		else if (_Pred(*_First2, *_First1))
			*_Dest++ = *_First2, ++_First2;
		else
			++_First1, ++_First2;
	_Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest);
	return (_STDEXT unchecked_copy(_First2, _Last2, _Dest));
	}

#if _SECURE_SCL

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (set_symmetric_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_INSECURE_DEPRECATE
_IF_NOT_CHK(_OutIt) set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#else

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#endif

		// TEMPLATE FUNCTION max_element
template<class _FwdIt> inline
	_FwdIt _Max_element(_FwdIt _First, _FwdIt _Last)
	{	// find largest element, using operator<
	_DEBUG_RANGE(_First, _Last);
	_FwdIt _Found = _First;
	if (_First != _Last)
		for (; ++_First != _Last; )
			if (_DEBUG_LT(*_Found, *_First))
				_Found = _First;
	return (_Found);
	}

template<class _FwdIt> inline
	_FwdIt max_element(_FwdIt _First, _FwdIt _Last)
	{	// find largest element, using operator<
	_ASSIGN_FROM_BASE(_First,
		_Max_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Last)));
	return (_First);
	}

		// TEMPLATE FUNCTION max_element WITH PRED
template<class _FwdIt,
	class _Pr> inline
	_FwdIt _Max_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find largest element, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_FwdIt _Found = _First;
	if (_First != _Last)
		for (; ++_First != _Last; )
			if (_DEBUG_LT_PRED(_Pred, *_Found, *_First))
				_Found = _First;
	return (_Found);
	}

template<class _FwdIt,
	class _Pr> inline
	_FwdIt max_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find largest element, using _Pred
	_ASSIGN_FROM_BASE(_First,
		_Max_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_First);
	}

		// TEMPLATE FUNCTION min_element
template<class _FwdIt> inline
	_FwdIt _Min_element(_FwdIt _First, _FwdIt _Last)
	{	// find smallest element, using operator<
	_DEBUG_RANGE(_First, _Last);
	_FwdIt _Found = _First;
	if (_First != _Last)
		for (; ++_First != _Last; )
			if (_DEBUG_LT(*_First, *_Found))
				_Found = _First;
	return (_Found);
	}

template<class _FwdIt> inline
	_FwdIt min_element(_FwdIt _First, _FwdIt _Last)
	{	// find smallest element, using operator<
	_ASSIGN_FROM_BASE(_First,
		_Min_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Last)));
	return (_First);
	}

		// TEMPLATE FUNCTION min_element WITH PRED
template<class _FwdIt,
	class _Pr> inline
	_FwdIt _Min_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find smallest element, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_FwdIt _Found = _First;
	if (_First != _Last)
		for (; ++_First != _Last; )
			if (_DEBUG_LT_PRED(_Pred, *_First, *_Found))
				_Found = _First;
	return (_Found);
	}

template<class _FwdIt,
	class _Pr> inline
	_FwdIt min_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// find smallest element, using _Pred
	_ASSIGN_FROM_BASE(_First,
		_Min_element(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
	return (_First);
	}

		// TEMPLATE FUNCTION next_permutation
template<class _BidIt> inline
	bool _Next_permutation(_BidIt _First, _BidIt _Last)
	{	// permute and test for pure ascending, using operator<
	_DEBUG_RANGE(_First, _Last);
	_BidIt _Next = _Last;
	if (_First == _Last || _First == --_Next)
		return (false);

	for (; ; )
		{	// find rightmost element smaller than successor
		_BidIt _Next1 = _Next;
		if (_DEBUG_LT(*--_Next, *_Next1))
			{	// swap with rightmost element that's smaller, flip suffix
			_BidIt _Mid = _Last;
			for (; !_DEBUG_LT(*_Next, *--_Mid); )
				;
			std::iter_swap(_Next, _Mid);
			std::reverse(_Next1, _Last);
			return (true);
			}

		if (_Next == _First)
			{	// pure descending, flip all
			std::reverse(_First, _Last);
			return (false);
			}
		}
	}

template<class _BidIt> inline
	bool next_permutation(_BidIt _First, _BidIt _Last)
	{	// permute and test for pure ascending, using operator<
	return _Next_permutation(_CHECKED_BASE(_First), _CHECKED_BASE(_Last));
	}

		// TEMPLATE FUNCTION next_permutation WITH PRED
template<class _BidIt,
	class _Pr> inline
	bool _Next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// permute and test for pure ascending, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_BidIt _Next = _Last;
	if (_First == _Last || _First == --_Next)
		return (false);

	for (; ; )
		{	// find rightmost element smaller than successor
		_BidIt _Next1 = _Next;
		if (_DEBUG_LT_PRED(_Pred, *--_Next, *_Next1))
			{	// swap with rightmost element that's smaller, flip suffix
			_BidIt _Mid = _Last;
			for (; !_DEBUG_LT_PRED(_Pred, *_Next, *--_Mid); )
				;
			std::iter_swap(_Next, _Mid);
			std::reverse(_Next1, _Last);
			return (true);
			}

		if (_Next == _First)
			{	// pure descending, flip all
			std::reverse(_First, _Last);
			return (false);
			}
		}
	}

template<class _BidIt,
	class _Pr> inline
	bool next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// permute and test for pure ascending, using _Pred
	return _Next_permutation(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred);
	}

		// TEMPLATE FUNCTION prev_permutation
template<class _BidIt> inline
	bool _Prev_permutation(_BidIt _First, _BidIt _Last)
	{	// reverse permute and test for pure descending, using operator<
	_DEBUG_RANGE(_First, _Last);
	_BidIt _Next = _Last;
	if (_First == _Last || _First == --_Next)
		return (false);
	for (; ; )
		{	// find rightmost element not smaller than successor
		_BidIt _Next1 = _Next;
		if (_DEBUG_LT(*_Next1, *--_Next))
			{	// swap with rightmost element that's not smaller, flip suffix
			_BidIt _Mid = _Last;
			for (; !_DEBUG_LT(*--_Mid, *_Next); )
				;
			std::iter_swap(_Next, _Mid);
			std::reverse(_Next1, _Last);
			return (true);
			}

		if (_Next == _First)
			{	// pure ascending, flip all
			std::reverse(_First, _Last);
			return (false);
			}
		}
	}

template<class _BidIt> inline
	bool prev_permutation(_BidIt _First, _BidIt _Last)
	{	// reverse permute and test for pure descending, using operator<
	return _Prev_permutation(_CHECKED_BASE(_First), _CHECKED_BASE(_Last));
	}

		// TEMPLATE FUNCTION prev_permutation WITH PRED
template<class _BidIt,
	class _Pr> inline
	bool _Prev_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// reverse permute and test for pure descending, using _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_BidIt _Next = _Last;
	if (_First == _Last || _First == --_Next)
		return (false);

	for (; ; )
		{	// find rightmost element not smaller than successor
		_BidIt _Next1 = _Next;
		if (_DEBUG_LT_PRED(_Pred, *_Next1, *--_Next))
			{	// swap with rightmost element that's not smaller, flip suffix
			_BidIt _Mid = _Last;
			for (; !_DEBUG_LT_PRED(_Pred, *--_Mid, *_Next); )
				;
			std::iter_swap(_Next, _Mid);
			std::reverse(_Next1, _Last);
			return (true);
			}

		if (_Next == _First)
			{	// pure ascending, flip all
			std::reverse(_First, _Last);
			return (false);
			}
		}
	}

template<class _BidIt,
	class _Pr> inline
	bool prev_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred)
	{	// reverse permute and test for pure descending, using _Pred
	return _Prev_permutation(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred);
	}

_STD_END

_STDEXT_BEGIN

template<class _InIt, class _OutIt, class _Fn1>
inline
	_OutIt unchecked_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
		return _STD _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
			_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutIt, class _Fn1>
inline
_IF_CHK(_OutIt) checked_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
	return _STD _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Fn1, size_t _Size>
inline
_OutElem* checked_transform(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Fn1 _Func)
	{
	return (checked_transform(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Func).base());
	}

template<class _InIt, class _OutIt, class _Fn1>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	{
	return _STD _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
	_OutIt unchecked_transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
		return _STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
			_STD _Iter_random(_First1, _First2), _STD _Iter_random(_First1, _Dest), 
			_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
_IF_CHK2_(_InIt2, _OutIt, _OutIt) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
	return _STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
		_STD _Iter_random(_First1, _First2), _STD _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InElem2, class _OutElem, class _Fn2, size_t _SizeFirst2, size_t _SizeDest>
inline
_OutElem* checked_transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (checked_transform(_First1, _Last1,
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest),
		_Func).base());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Fn2, size_t _SizeDest>
inline
_IF_CHK_(_InIt2, _OutElem*) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (_STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest), _Func,
		_STD _Iter_random(_First1, _First2), _STD _Iter_cat(_First1),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()).base());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Fn2, size_t _SizeDest>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK_(_InIt2, _OutElem*) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutElem (&_Dest)[_SizeDest], _Fn2 _Func)
	{
	return (_STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
		_STDEXT make_checked_array_iterator(_Dest, _SizeDest), _Func,
		_STD _Iter_random(_First1, _First2), _STD _Iter_cat(_First1),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()).base());
	}

template<class _InIt1, class _InElem2, class _OutIt, class _Fn2, size_t _SizeFirst2>
inline
_IF_CHK(_OutIt) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutIt _Dest, _Fn2 _Func)
	{
	return (_STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_Dest, _Func,
		_STD _Iter_cat(_First1), _STD _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt1, class _InElem2, class _OutIt, class _Fn2, size_t _SizeFirst2>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InElem2 (&_First2)[_SizeFirst2],
		_OutIt _Dest, _Fn2 _Func)
	{
	return (_STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_STDEXT make_checked_array_iterator(_First2, _SizeFirst2),
		_Dest, _Func,
		_STD _Iter_cat(_First1), _STD _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK2_(_InIt2, _OutIt, _OutIt) checked_transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
		_OutIt _Dest, _Fn2 _Func)
	{
	return _STD _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
		_STD _Iter_random(_First1, _First2), _STD _Iter_random(_First1, _Dest),
		_STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt1, class _FwdIt2>
inline
	_FwdIt2 unchecked_swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _STD _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_STD _Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt1, class _FwdIt2>
inline
_IF_CHK(_FwdIt2) checked_swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _STD _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_STD _Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt1, class _FwdElem2, size_t _Size>
inline
_FwdElem2* checked_swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdElem2 (&_First2)[_Size])
	{
		return (checked_swap_ranges(_First1, _Last1, _STDEXT make_checked_array_iterator(_First2, _Size)).base());
	}

template<class _FwdIt1, class _FwdIt2>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_FwdIt2) checked_swap_ranges(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2)
	{
		return _STD _Swap_ranges(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2,
			_STD _Iter_random(_First1, _First2), _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt unchecked_replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
		return _STD _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
			_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_IF_CHK(_OutIt) checked_replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return _STD _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Ty, size_t _Size>
inline
_OutElem* checked_replace_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size],
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return (checked_replace_copy(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Oldval, _Newval).base());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
		const _Ty& _Oldval, const _Ty& _Newval)
	{	// copy replacing each matching _Oldval with _Newval
	return _STD _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
	_OutIt unchecked_replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
		return _STD _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
			_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
_IF_CHK(_OutIt) checked_replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return _STD _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Pr, class _Ty, size_t _Size>
inline
_OutElem* checked_replace_copy_if(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size],
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return (checked_replace_copy_if(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Pred, _Val).base());
	}

template<class _InIt,
	class _OutIt,
	class _Pr,
	class _Ty> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred, const _Ty& _Val)
	{	// copy replacing each satisfying _Pred with _Val
	return _STD _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
		_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
	void unchecked_generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
		_STD _Generate_n(_Dest, _Count, _Func,
			_STD _Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
void checked_generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func, _IF_CHK_(_OutIt, _Diff) = 0)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_STD _Generate_n(_Dest, _Count, _Func,
		_STD _Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

template<class _OutElem, class _Diff, class _Fn0, size_t _Size>
inline
void checked_generate_n(_OutElem (&_Dest)[_Size], _Diff _Count, _Fn0 _Func)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	checked_generate_n(_STDEXT make_checked_array_iterator(_Dest, _Size), _Count, _Func);
	}

template<class _OutIt,
	class _Diff,
	class _Fn0> inline
_SCL_CHECKED_ALGORITHM_WARN
void checked_generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func, _IF_NOT_CHK_(_OutIt, _Diff) = 0)
	{	// replace [_Dest, _Dest + _Count) with _Func()
	_STD _Generate_n(_Dest, _Count, _Func,
		_STD _Iter_cat(_Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
	_OutIt unchecked_remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
		return _STD _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_IF_CHK(_OutIt) checked_remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
	return _STD _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val, _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Ty, size_t _Size>
inline
_OutElem* checked_remove_copy(_InIt _First, _InIt _Last,
		_OutElem (&_Dest)[_Size], const _Ty& _Val)
	{	// copy omitting each matching _Val
	return (checked_remove_copy(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size),
		_Val).base());
	}

template<class _InIt,
	class _OutIt,
	class _Ty> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_remove_copy(_InIt _First, _InIt _Last,
		_OutIt _Dest, const _Ty& _Val)
	{	// copy omitting each matching _Val
	return _STD _Remove_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Val, _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
		return _STD _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return _STD _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_remove_copy_if(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return (checked_remove_copy_if(_First, _Last,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_remove_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy omitting each element satisfying _Pred
	return _STD _Remove_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt,
	class _OutIt> inline
	_OutIt unchecked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest,
			_STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt, class _OutElem, size_t _Size>
inline
_OutElem* checked_unique_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size])
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		(checked_unique_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base()));
	}

template<class _InIt,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest)
	{	// copy compressing pairs that match
	return (_First == _Last ? _Dest :
		_STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred,
			_STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _InIt, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_unique_copy(_InIt _First, _InIt _Last, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: (checked_unique_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base()));
	}

template<class _InIt,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
	{	// copy compressing pairs satisfying _Pred
	return (_First == _Last ? _Dest
		: _STD _Unique_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _STD _Iter_cat(_First), _STD _Range_checked_iterator_tag()));
	}

template<class _BidIt,
	class _OutIt> inline
	_OutIt unchecked_reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
		return _STD _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest,
			_STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _BidIt,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
	return _STD _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, size_t _Size>
inline
_OutElem* checked_reverse_copy(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size])
	{	// copy reversing elements in [_First, _Last)
	return (checked_reverse_copy(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _BidIt,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_reverse_copy(_BidIt _First, _BidIt _Last, _OutIt _Dest)
	{	// copy reversing elements in [_First, _Last)
	return _STD _Reverse_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _STD _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt,
	class _OutIt> inline
	_OutIt unchecked_rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{	// copy rotating [_First, _Last)
		return _STD _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt, class _OutIt>
inline
_IF_CHK(_OutIt) checked_rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{
		return _STD _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _FwdIt, class _OutElem, size_t _Size>
inline
_OutElem* checked_rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutElem (&_Dest)[_Size])
	{
		return (checked_rotate_copy(_First, _Mid, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _FwdIt, class _OutIt>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_rotate_copy(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last, _OutIt _Dest)
	{
		return _STD _Rotate_copy(_First, _Mid, _Last, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt unchecked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
		return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
			_STD _Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
	return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
		_STD _Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// copy merging ranges, both using operator<
	return (checked_merge(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// copy merging ranges, both using operator<
	return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
		_STD _Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
		return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest, _Pred,
			_STD _Iter_random(_First1, _First2,_Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred,
		_STD _Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return (checked_merge(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_merge(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  copy merging ranges, both using _Pred
	return _STD _Merge(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred,
		_STD _Iter_random(_First1, _First2, _Dest), _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
	_BidIt3 _Unchecked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
_IF_CHK(_BidIt3) _Checked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_BidIt3) _Checked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
	_BidIt3 _Unchecked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
_IF_CHK(_BidIt3) _Checked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt1, class _BidIt2, class _BidIt3, class _Pr>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_BidIt3) _Checked_merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
		_BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Pr _Pred)
	{
		return _STD _Merge_backward(_First1, _Last1, _First2, _Last2, _Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff>
inline
	void _Unchecked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff>
inline
_IF_CHK_(_OutIt, void) _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, class _Diff, size_t _Size>
inline
void _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size],
		_Diff _Chunk, _Diff _Count)
	{
		_STD _Chunked_merge(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK_(_OutIt, void) _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
	void _Unchecked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
_IF_CHK_(_OutIt, void) _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutElem, class _Diff, class _Pr, size_t _Size>
inline
void _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutElem (&_Dest)[_Size],
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_STD _Chunked_merge(_First, _Last, _STDEXT make_checked_array_iterator(_Dest, _Size), _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _BidIt, class _OutIt, class _Diff, class _Pr>
inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK_(_OutIt, void) _Checked_chunked_merge(_BidIt _First, _BidIt _Last, _OutIt _Dest,
		_Diff _Chunk, _Diff _Count, _Pr _Pred)
	{
		_STD _Chunked_merge(_First, _Last, _Dest, _Chunk, _Count, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt unchecked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
		return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (checked_set_union(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
		return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest, _Pred,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (checked_set_union(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_union(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// OR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_union(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt unchecked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
		return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (checked_set_intersection(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
		return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest, _Pred,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (checked_set_intersection(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_intersection(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// AND sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_intersection(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt unchecked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
		return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return (checked_set_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// take set [_First2, _Last2) from [_First1, _Last1), using operator<
	return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
		return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest, _Pred,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return (checked_set_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	//  take set [_First2, _Last2) from [_First1, _Last1), using _Pred
	return _STD _Set_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
	_OutIt unchecked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
		return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_IF_CHK(_OutIt) checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, size_t _Size>
inline
_OutElem* checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size])
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return (checked_set_symmetric_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size)).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using operator<
	return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
	_OutIt unchecked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
		return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _CHECKED_BASE(_First2), _CHECKED_BASE(_Last2), _Dest, _Pred,
			_STD _Range_checked_iterator_tag());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_IF_CHK(_OutIt) checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

template<class _InIt1, class _InIt2, class _OutElem, class _Pr, size_t _Size>
inline
_OutElem* checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutElem (&_Dest)[_Size], _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return (checked_set_symmetric_difference(_First1, _Last1, _First2, _Last2,
		_STDEXT make_checked_array_iterator(_Dest, _Size), _Pred).base());
	}

template<class _InIt1,
	class _InIt2,
	class _OutIt,
	class _Pr> inline
_SCL_CHECKED_ALGORITHM_WARN
_IF_NOT_CHK(_OutIt) checked_set_symmetric_difference(_InIt1 _First1, _InIt1 _Last1,
		_InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred)
	{	// XOR sets [_First1, _Last1) and [_First2, _Last2), using _Pred
	return _STD _Set_symmetric_difference(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1),
		_CHECKED_BASE(_First2), _CHECKED_BASE(_Last2),
		_Dest, _Pred, _STD _Range_checked_iterator_tag());
	}

#if _HAS_TRADITIONAL_STL
		// TEMPLATE FUNCTION count
template<class _InIt,
	class _Ty,
	class _Diff> inline
	void count(_InIt _First, _InIt _Last, const _Ty& _Val, _Diff &_Ans)
	{	// count elements that match _Val
	_DEBUG_RANGE(_First, _Last);
	_Diff _Count = 0;

	for (; _First != _Last; ++_First)
		if (*_First == _Val)
			++_Count;
	_Ans = _Count;
	}

		// TEMPLATE FUNCTION count_if
template<class _InIt,
	class _Pr,
	class _Diff> inline
	void count_if(_InIt _First, _InIt _Last, _Pr _Pred, _Diff &_Ans)
	{	// count elements satisfying _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_Diff _Count = 0;

	for (; _First != _Last; ++_First)
		if (_Pred(*_First))
			++_Count;
	_Ans = _Count;
	}

		// TEMPLATE FUNCTION is_heap
template<class _RanIt,
	class _Diff> inline
	bool _Is_heap(_RanIt _First, _RanIt _Last, _Diff *)
	{	// test if range is a heap ordered by operator<
	_DEBUG_RANGE(_First, _Last);
	_Diff _Size = _Last - _First;

	if (2 <= _Size)
		for (_Diff _Off = 0; ++_Off < _Size; )
			if (_DEBUG_LT(*(_First + (_Off - 1) / 2), *(_First + _Off)))
				return (false);
	return (true);
	}

template<class _RanIt>
	bool is_heap(_RanIt _First, _RanIt _Last)
		{	// test if range is a heap ordered by operator<
		return (_Is_heap(_First, _Last, _Dist_type(_First)));
		}

		// TEMPLATE FUNCTION is_heap WITH PRED
template<class _RanIt,
	class _Diff,
	class _Pr> inline
	bool _Is_heap(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *)
	{	// test if range is a heap ordered by _Pred
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	_Diff _Size = _Last - _First;

	if (2 <= _Size)
		for (_Diff _Off = 0; ++_Off < _Size; )
			if (_DEBUG_LT_PRED(_Pred, *(_First + (_Off - 1) / 2),
				*(_First + _Off)))
				return (false);
	return (true);
	}

template<class _RanIt,
	class _Pr>
	bool is_heap(_RanIt _First, _RanIt _Last, _Pr _Pred)
		{	// test if range is a heap ordered by _Pred
		return (_Is_heap(_First, _Last, _Pred, _Dist_type(_First)));
		}

		// TEMPLATE FUNCTION is_sorted
template<class _FwdIt> inline
	bool is_sorted(_FwdIt _First, _FwdIt _Last)
	{	// test is range is ordered by operator<
	_DEBUG_RANGE(_First, _Last);
	for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
		if (_DEBUG_LT(*_Next, *_First))
			return (false);
	return (true);
	}

		// TEMPLATE FUNCTION is_sorted WITH PRED
template<class _FwdIt,
	class _Pr> inline
	bool is_sorted(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	{	// test if range is ordered by predicate, forward iterators
	_DEBUG_RANGE(_First, _Last);
	_DEBUG_POINTER(_Pred);
	for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
		if (_DEBUG_LT_PRED(_Pred, *_Next, *_First))
			return (false);
	return (true);
	}
 #endif /* _HAS_TRADITIONAL_STL */

_STDEXT_END

  #pragma warning(default: 4244)

#ifdef _MSC_VER
 #pragma warning(pop)
 #pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* RC_INVOKED */
#endif /* _ALGORITHM_ */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 */

/*
 * Copyright (c) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.05:0009 */
